From fbbdd8d2cc52d2d1fb72f099e6508938048134aa Mon Sep 17 00:00:00 2001 From: Arminek Date: Wed, 17 May 2017 17:03:46 +0200 Subject: [PATCH 1/6] [ElasticSearch] Rename & remove ui & bump dsl to 5.0 --- composer.json | 13 +- ...tering_list_of_products_by_options.feature | 8 +- ...ng_list_of_products_by_price_range.feature | 2 +- .../searching_products_by_name.feature | 12 +- src/Controller/SearchController.php | 208 +----------------- .../Compiler/RegisterFilterTypePass.php | 2 +- .../RegisterSearchCriteriaApplicatorPass.php | 2 +- src/DependencyInjection/Configuration.php | 4 +- .../LakionSyliusElasticSearchExtension.php | 36 --- .../SyliusElasticSearchExtension.php | 32 +++ ...ilterSetConfigurationNotFoundException.php | 2 +- .../MissingQueryParameterException.php | 2 +- src/Form/Configuration/Filter.php | 2 +- src/Form/Configuration/FilterSet.php | 2 +- .../Provider/FilterSetProvider.php | 4 +- .../Provider/FilterSetProviderInterface.php | 6 +- .../Provider/FromArrayFilterSetProvider.php | 6 +- src/Form/DataMapper/CriteriaDataMapper.php | 4 +- src/Form/Type/FilterSetType.php | 8 +- src/Form/Type/OptionCodeFilterType.php | 8 +- src/Form/Type/ProductPriceRangeFilterType.php | 4 +- src/Form/Type/SearchType.php | 4 +- src/Resources/config/routing.yml | 34 --- src/Resources/config/services.xml | 2 +- src/Resources/config/services/controller.xml | 2 +- .../filter_set_configuration_provider.xml | 4 +- src/Resources/config/services/form.xml | 8 +- .../config/services/query_factory.xml | 16 +- .../services/search_criteria_applicator.xml | 24 +- .../config/services/search_engine.xml | 2 +- .../views/Product/_globalSearch.html.twig | 4 - src/Resources/views/Product/index.html.twig | 36 --- .../views/Product/indexByTaxon.html.twig | 36 --- src/Search/Criteria/Criteria.php | 2 +- src/Search/Criteria/Filtering.php | 2 +- .../Filtering/ProductHasOptionCodesFilter.php | 2 +- .../Filtering/ProductInChannelFilter.php | 2 +- .../Filtering/ProductInPriceRangeFilter.php | 2 +- .../Filtering/ProductInTaxonFilter.php | 2 +- src/Search/Criteria/Ordering.php | 2 +- src/Search/Criteria/Paginating.php | 2 +- src/Search/Criteria/SearchPhrase.php | 2 +- ...roductHasMultipleOptionCodesApplicator.php | 12 +- .../Filter/ProductInChannelApplicator.php | 12 +- .../Filter/ProductInPriceRangeApplicator.php | 12 +- .../Filter/ProductInTaxonApplicator.php | 16 +- .../Query/MatchProductByNameApplicator.php | 11 +- .../Applicator/SearchCriteriaApplicator.php | 2 +- .../SearchCriteriaApplicatorInterface.php | 3 +- .../Applicator/Sort/SortByFieldApplicator.php | 10 +- src/Search/Elastic/ElasticSearchEngine.php | 10 +- .../Query/EmptyCriteriaQueryFactory.php | 2 +- .../Query/MatchProductNameQueryFactory.php | 8 +- .../ProductHasOptionCodeQueryFactory.php | 8 +- .../Query/ProductInChannelQueryFactory.php | 8 +- .../Query/ProductInMainTaxonQueryFactory.php | 6 +- .../Query/ProductInPriceRangeQueryFactory.php | 8 +- .../ProductInProductTaxonsQueryFactory.php | 8 +- .../Factory/Query/QueryFactoryInterface.php | 4 +- .../Elastic/Factory/Search/SearchFactory.php | 2 +- .../Factory/Search/SearchFactoryInterface.php | 2 +- .../Factory/Sort/SortByFieldQueryFactory.php | 4 +- .../Factory/Sort/SortFactoryInterface.php | 4 +- src/Search/SearchEngineInterface.php | 4 +- ...ndle.php => SyliusElasticSearchPlugin.php} | 11 +- tests/Application/app/AppKernel.php | 2 +- tests/Application/app/config/config.yml | 4 +- .../Context/Domain/Shop/ProductContext.php | 19 +- .../Context/Hook/ElasticSearchContext.php | 2 +- tests/Behat/Context/Setup/ProductContext.php | 4 +- .../Behat/Context/Ui/Shop/ProductContext.php | 163 -------------- tests/Behat/Page/Product/IndexPage.php | 101 --------- .../Behat/Page/Product/IndexPageInterface.php | 50 ----- tests/Behat/Resources/services.xml | 4 +- .../Resources/services/searching_products.xml | 11 +- tests/Behat/Resources/suites.yml | 1 - .../shop/ui/product/searching_products.yml | 19 -- .../Behat/Services/ElasticSearchSuspender.php | 2 +- tests/Behat/Services/SuspenderInterface.php | 2 +- .../Compiler/RegisterFilterTypePassTest.php | 4 +- ...gisterSearchCriteriaApplicatorPassTest.php | 4 +- .../DependencyInjection/ConfigurationTest.php | 4 +- 82 files changed, 236 insertions(+), 884 deletions(-) delete mode 100644 src/DependencyInjection/LakionSyliusElasticSearchExtension.php create mode 100644 src/DependencyInjection/SyliusElasticSearchExtension.php delete mode 100644 src/Resources/views/Product/_globalSearch.html.twig delete mode 100644 src/Resources/views/Product/index.html.twig delete mode 100644 src/Resources/views/Product/indexByTaxon.html.twig rename src/{LakionSyliusElasticSearchBundle.php => SyliusElasticSearchPlugin.php} (53%) delete mode 100644 tests/Behat/Context/Ui/Shop/ProductContext.php delete mode 100644 tests/Behat/Page/Product/IndexPage.php delete mode 100644 tests/Behat/Page/Product/IndexPageInterface.php delete mode 100644 tests/Behat/Resources/suites/shop/ui/product/searching_products.yml diff --git a/composer.json b/composer.json index 9307021..5d033f3 100644 --- a/composer.json +++ b/composer.json @@ -1,13 +1,13 @@ { - "name": "lakion/sylius-elastic-search-bundle", + "name": "sylius/elastic-search-plugin", "type": "sylius-bundle", "description": "Elastic search integration for Sylius.", "license": "MIT", "authors": [ { "name": "Arkadiusz Krakowiak", - "email": "arkadiusz.krakowiak@lakion.com", - "homepage": "http://lakion.com" + "email": "arkadiusz.k.e@gmail.com", + "homepage": "http://github.com/arminek" } ], "require": { @@ -16,14 +16,13 @@ "sylius/sylius": "dev-master", "friendsofsymfony/elastica-bundle": "^4.0", - "ongr/elasticsearch-dsl": "^2.0" + "ongr/elasticsearch-dsl": "^5.0" }, "require-dev": { "behat/behat": "^3.2", "behat/mink": "^1.7", "behat/mink-browserkit-driver": "^1.3", "behat/mink-extension": "^2.2", - "behat/mink-selenium2-driver": "^1.3", "friends-of-behat/context-service-extension": "^0.3", "friends-of-behat/cross-container-extension": "^0.2", "friends-of-behat/performance-extension": "^1.0", @@ -44,8 +43,8 @@ "prefer-stable": true, "autoload": { "psr-4": { - "Lakion\\SyliusElasticSearchBundle\\": "src/", - "Tests\\Lakion\\SyliusElasticSearchBundle\\": "tests/" + "Sylius\\ElasticSearchPlugin\\": "src/", + "Tests\\Sylius\\ElasticSearchPlugin\\": "tests/" } } } diff --git a/features/shop/product/searching/filtering_list_of_products_by_options.feature b/features/shop/product/searching/filtering_list_of_products_by_options.feature index 2ced0a9..9ec826e 100644 --- a/features/shop/product/searching/filtering_list_of_products_by_options.feature +++ b/features/shop/product/searching/filtering_list_of_products_by_options.feature @@ -8,22 +8,22 @@ Feature: Filtering list of products by options Given the store operates on a single channel in "United States" And the store has 10 Mugs, 20 Stickers and 25 Books - @domain @ui + @domain Scenario: Filtering products by their type When I filter them by double mug type Then I should see 10 products on the list - @domain @ui + @domain Scenario: Filtering product by their type or size When I filter them by double mug type or sticker size 7 Then I should see 30 products on the list - @domain @ui + @domain Scenario: Filtering product by their size When I filter them by stickier size 7 Then I should see 20 products on the list - @domain @ui + @domain Scenario: List of all products without filtering When I view the list of the products without filtering Then I should see 55 products on the list diff --git a/features/shop/product/searching/filtering_list_of_products_by_price_range.feature b/features/shop/product/searching/filtering_list_of_products_by_price_range.feature index 41353a5..c69f4f1 100644 --- a/features/shop/product/searching/filtering_list_of_products_by_price_range.feature +++ b/features/shop/product/searching/filtering_list_of_products_by_price_range.feature @@ -11,7 +11,7 @@ Feature: Filtering list of products by price range And the store also has a product "LOTR T-Shirt" priced at "$300" And the store also has a product "Breaking Bad T-Shirt" priced at "$50" - @domain @ui + @domain Scenario: Filtering products by price range When I filter them by price between "$100" and "$200" Then I should see 2 products on the list diff --git a/features/shop/product/searching/searching_products_by_name.feature b/features/shop/product/searching/searching_products_by_name.feature index 65c1acc..de700d6 100644 --- a/features/shop/product/searching/searching_products_by_name.feature +++ b/features/shop/product/searching/searching_products_by_name.feature @@ -17,37 +17,37 @@ Feature: Searching products by name And the store has a product "Westworld Hosts T-Shirt" And the store has a product "Westworld Hopkins T-Shirt" - @domain @ui + @domain Scenario: Searching products by name When I search for products with name "Banana" Then I should see 1 products on the list And It should be "Banana T-Shirt" - @domain @ui + @domain Scenario: Searching products by name When I search for products with name "Star" Then I should see 2 products on the list And It should be "Star Wars T-Shirt", "Star Wars Rogue T-Shirt" - @domain @ui + @domain Scenario: Searching products by name When I search for products with name "Bad" Then I should see 4 products on the list And It should be "Breaking Bad Saul T-Shirt", "Breaking Bad Mike T-Shirt", "Breaking Bad Jesse T-Shirt", "Breaking Bad Heisenberg T-Shirt" - @domain @ui + @domain Scenario: Searching products by name When I search for products with name "Westworld" Then I should see 3 products on the list And It should be "Westworld T-Shirt", "Westworld Hosts T-Shirt", "Westworld Hopkins T-Shirt" - @domain @ui + @domain Scenario: Searching products by name When I search for products with name "Hopkins" Then I should see 1 products on the list And It should be "Westworld Hopkins T-Shirt" - @domain @ui + @domain Scenario: Searching products by name When I search for products with name "T-Shirt" Then I should see 10 products on the list diff --git a/src/Controller/SearchController.php b/src/Controller/SearchController.php index 5ea01ed..629ebba 100644 --- a/src/Controller/SearchController.php +++ b/src/Controller/SearchController.php @@ -9,15 +9,15 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Controller; +namespace Sylius\ElasticSearchPlugin\Controller; use FOS\RestBundle\View\ConfigurableViewHandlerInterface; use FOS\RestBundle\View\View; -use Lakion\SyliusElasticSearchBundle\Form\Type\FilterSetType; -use Lakion\SyliusElasticSearchBundle\Search\Criteria\Criteria; -use Lakion\SyliusElasticSearchBundle\Search\Criteria\Filtering\ProductInChannelFilter; -use Lakion\SyliusElasticSearchBundle\Search\Criteria\Filtering\ProductInTaxonFilter; -use Lakion\SyliusElasticSearchBundle\Search\SearchEngineInterface; +use Sylius\ElasticSearchPlugin\Form\Type\FilterSetType; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; +use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInChannelFilter; +use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInTaxonFilter; +use Sylius\ElasticSearchPlugin\Search\SearchEngineInterface; use Sylius\Component\Core\Context\ShopperContextInterface; use Sylius\Component\Taxonomy\Repository\TaxonRepositoryInterface; use Symfony\Component\Form\FormFactoryInterface; @@ -40,211 +40,21 @@ final class SearchController */ private $searchEngine; - /** - * @var FormFactoryInterface - */ - private $formFactory; - - /** - * @var TaxonRepositoryInterface - */ - private $taxonRepository; - - /** - * @var ShopperContextInterface - */ - private $shopperContext; - /** * @param ConfigurableViewHandlerInterface $restViewHandler * @param SearchEngineInterface $searchEngine - * @param FormFactoryInterface $formFactory - * @param TaxonRepositoryInterface $taxonRepository - * @param ShopperContextInterface $shopperContext */ - public function __construct( - ConfigurableViewHandlerInterface $restViewHandler, - SearchEngineInterface $searchEngine, - FormFactoryInterface $formFactory, - TaxonRepositoryInterface $taxonRepository, - ShopperContextInterface $shopperContext - ) { + public function __construct(ConfigurableViewHandlerInterface $restViewHandler, SearchEngineInterface $searchEngine) + { $this->restViewHandler = $restViewHandler; $this->searchEngine = $searchEngine; - $this->formFactory = $formFactory; - $this->taxonRepository = $taxonRepository; - $this->shopperContext = $shopperContext; - } - - /** - * @param Request $request - * - * @return Response - */ - public function filterAction(Request $request) - { - $view = View::create(); - if ($this->isHtmlRequest($request)) { - $view->setTemplate($this->getTemplateFromRequest($request)); - } - - $form = $this->formFactory->create( - FilterSetType::class, - Criteria::fromQueryParameters( - $this->getResourceClassFromRequest($request), - [ - 'per_page' => $request->get('per_page'), - new ProductInChannelFilter($this->shopperContext->getChannel()->getCode()) - ] - ), - ['filter_set' => $this->getFilterSetFromRequest($request)] - ); - $form->handleRequest($request); - - /** @var Criteria $criteria */ - $criteria = $form->getData(); - - $result = $this->searchEngine->match($criteria); - $partialResult = $result->getResults($criteria->getPaginating()->getOffset(), $criteria->getPaginating()->getItemsPerPage()); - - $view->setData([ - 'products' => $partialResult->toArray(), - 'form' => $form->createView(), - 'criteria' => $criteria, - ]); - - return $this->restViewHandler->handle($view); } /** - * @param string $slug * @param Request $request - * - * @return Response - */ - public function filterByTaxonAction($slug, Request $request) - { - $view = View::create(); - if ($this->isHtmlRequest($request)) { - $view->setTemplate($this->getTemplateFromRequest($request)); - } - $locale = $this->shopperContext->getLocaleCode(); - $taxon = $this->taxonRepository->findOneBySlug($slug, $locale); - - $form = $this->formFactory->create( - FilterSetType::class, - Criteria::fromQueryParameters( - $this->getResourceClassFromRequest($request), - ['per_page' => $request->get('per_page')] - ), - ['filter_set' => $taxon->getCode()] - ); - $form->handleRequest($request); - - /** @var Criteria $criteria */ - $criteria = $form->getData(); - $criteria = Criteria::fromQueryParameters( - $criteria->getResourceAlias(), - array_merge($criteria->getFiltering()->getFields(), [ - new ProductInTaxonFilter($taxon->getCode()), - new ProductInChannelFilter($this->shopperContext->getChannel()->getCode()) - ] - ) - ); - - $result = $this->searchEngine->match($criteria); - $partialResult = $result->getResults($criteria->getPaginating()->getOffset(), $criteria->getPaginating()->getItemsPerPage()); - - $view->setData([ - 'products' => $partialResult->toArray(), - 'form' => $form->createView(), - 'criteria' => $criteria, - ]); - - return $this->restViewHandler->handle($view); - } - - /** - * @param string $filterSetName - * - * @return Response */ - public function renderFilterSetAction(Request $request, $filterSetName) + public function searchAction(Request $request) { - $view = View::create(); - $view->setTemplate($this->getTemplateFromRequest($request)); - if (!$this->isHtmlRequest($request)) { - throw new HttpException(Response::HTTP_BAD_REQUEST); - } - - $form = $this->formFactory->create( - FilterSetType::class, - null, - ['filter_set' => $filterSetName] - ); - - $view->setData([ - 'form' => $form->createView(), - ]); - - return $this->restViewHandler->handle($view); - } - - /** - * @param Request $request - * - * @return string - */ - private function getTemplateFromRequest(Request $request) - { - $syliusAttributes = $request->attributes->get('_sylius'); - - if (!isset($syliusAttributes['template'])) { - throw new HttpException(Response::HTTP_BAD_REQUEST, 'You need to configure template in routing!'); - } - - return $syliusAttributes['template']; - } - - /** - * @param Request $request - * - * @return string - */ - private function getResourceClassFromRequest(Request $request) - { - $syliusAttributes = $request->attributes->get('_sylius'); - - if (!isset($syliusAttributes['resource_class'])) { - throw new HttpException(Response::HTTP_BAD_REQUEST, 'You need to configure resource class in routing!'); - } - - return $syliusAttributes['resource_class']; - } - - /** - * @param Request $request - * - * @return bool - */ - private function isHtmlRequest(Request $request) - { - return !$request->isXmlHttpRequest() && 'html' === $request->getRequestFormat(); - } - - /** - * @param Request $request - * - * @return string - */ - private function getFilterSetFromRequest(Request $request) - { - $syliusAttributes = $request->attributes->get('_sylius'); - - if (!isset($syliusAttributes['filter_set'])) { - throw new HttpException(Response::HTTP_BAD_REQUEST, 'You need to configure filter set in routing!'); - } - return $syliusAttributes['filter_set']; } } diff --git a/src/DependencyInjection/Compiler/RegisterFilterTypePass.php b/src/DependencyInjection/Compiler/RegisterFilterTypePass.php index d8b8b89..bff7015 100644 --- a/src/DependencyInjection/Compiler/RegisterFilterTypePass.php +++ b/src/DependencyInjection/Compiler/RegisterFilterTypePass.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\DependencyInjection\Compiler; +namespace Sylius\ElasticSearchPlugin\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; diff --git a/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php b/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php index 40fc11f..6a34660 100644 --- a/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php +++ b/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\DependencyInjection\Compiler; +namespace Sylius\ElasticSearchPlugin\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index d8d826d..ec1373d 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\DependencyInjection; +namespace Sylius\ElasticSearchPlugin\DependencyInjection; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; @@ -26,7 +26,7 @@ final class Configuration implements ConfigurationInterface public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('lakion_sylius_elastic_search'); + $rootNode = $treeBuilder->root('sylius_elastic_search'); $this->buildFilterSetNode($rootNode); diff --git a/src/DependencyInjection/LakionSyliusElasticSearchExtension.php b/src/DependencyInjection/LakionSyliusElasticSearchExtension.php deleted file mode 100644 index 677ca09..0000000 --- a/src/DependencyInjection/LakionSyliusElasticSearchExtension.php +++ /dev/null @@ -1,36 +0,0 @@ -load('services.xml'); - $this->createFilterSetsParameter($config, $container); - } - - /** - * @param array $config - * @param ContainerBuilder $container - */ - private function createFilterSetsParameter(array $config, ContainerBuilder $container) - { - $container->setParameter('lakion_sylius_elastic_search.filter_sets', reset($config)['filter_sets']); - } -} diff --git a/src/DependencyInjection/SyliusElasticSearchExtension.php b/src/DependencyInjection/SyliusElasticSearchExtension.php new file mode 100644 index 0000000..3869305 --- /dev/null +++ b/src/DependencyInjection/SyliusElasticSearchExtension.php @@ -0,0 +1,32 @@ +processConfiguration($this->getConfiguration([], $container), $configs); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + + $loader->load('services.xml'); + $this->createFilterSetsParameter($config['filter_sets'], $container); + } + + /** + * @param array $config + * @param ContainerBuilder $container + */ + private function createFilterSetsParameter(array $config, ContainerBuilder $container) + { + $container->setParameter('lakion_sylius_elastic_search.filter_sets', $config); + } +} diff --git a/src/Exception/FilterSetConfigurationNotFoundException.php b/src/Exception/FilterSetConfigurationNotFoundException.php index 1cc8fc6..80a5c21 100644 --- a/src/Exception/FilterSetConfigurationNotFoundException.php +++ b/src/Exception/FilterSetConfigurationNotFoundException.php @@ -1,6 +1,6 @@ diff --git a/src/Exception/MissingQueryParameterException.php b/src/Exception/MissingQueryParameterException.php index b8a7bcf..351b689 100644 --- a/src/Exception/MissingQueryParameterException.php +++ b/src/Exception/MissingQueryParameterException.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Exception; +namespace Sylius\ElasticSearchPlugin\Exception; /** * @author Arkadiusz Krakowiak diff --git a/src/Form/Configuration/Filter.php b/src/Form/Configuration/Filter.php index a88191c..058cfe1 100644 --- a/src/Form/Configuration/Filter.php +++ b/src/Form/Configuration/Filter.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Form\Configuration; +namespace Sylius\ElasticSearchPlugin\Form\Configuration; /** * @author Arkadiusz Krakowiak diff --git a/src/Form/Configuration/FilterSet.php b/src/Form/Configuration/FilterSet.php index 95fea84..4379e91 100644 --- a/src/Form/Configuration/FilterSet.php +++ b/src/Form/Configuration/FilterSet.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Form\Configuration; +namespace Sylius\ElasticSearchPlugin\Form\Configuration; /** * @author Arkadiusz Krakowiak diff --git a/src/Form/Configuration/Provider/FilterSetProvider.php b/src/Form/Configuration/Provider/FilterSetProvider.php index 29bc8b6..84a48cd 100644 --- a/src/Form/Configuration/Provider/FilterSetProvider.php +++ b/src/Form/Configuration/Provider/FilterSetProvider.php @@ -1,8 +1,8 @@ diff --git a/src/Form/Configuration/Provider/FromArrayFilterSetProvider.php b/src/Form/Configuration/Provider/FromArrayFilterSetProvider.php index 27e2b80..107e46a 100644 --- a/src/Form/Configuration/Provider/FromArrayFilterSetProvider.php +++ b/src/Form/Configuration/Provider/FromArrayFilterSetProvider.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Form\Configuration\Provider; +namespace Sylius\ElasticSearchPlugin\Form\Configuration\Provider; -use Lakion\SyliusElasticSearchBundle\Exception\FilterSetConfigurationNotFoundException; -use Lakion\SyliusElasticSearchBundle\Form\Configuration\FilterSet; +use Sylius\ElasticSearchPlugin\Exception\FilterSetConfigurationNotFoundException; +use Sylius\ElasticSearchPlugin\Form\Configuration\FilterSet; /** * @author Arkadiusz Krakowiak diff --git a/src/Form/DataMapper/CriteriaDataMapper.php b/src/Form/DataMapper/CriteriaDataMapper.php index 2166ffa..1ebee20 100644 --- a/src/Form/DataMapper/CriteriaDataMapper.php +++ b/src/Form/DataMapper/CriteriaDataMapper.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Form\DataMapper; +namespace Sylius\ElasticSearchPlugin\Form\DataMapper; -use Lakion\SyliusElasticSearchBundle\Search\Criteria\Criteria; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Symfony\Component\Form\DataMapperInterface; /** diff --git a/src/Form/Type/FilterSetType.php b/src/Form/Type/FilterSetType.php index 85bf19a..8ee21a1 100644 --- a/src/Form/Type/FilterSetType.php +++ b/src/Form/Type/FilterSetType.php @@ -9,11 +9,11 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Form\Type; +namespace Sylius\ElasticSearchPlugin\Form\Type; -use Lakion\SyliusElasticSearchBundle\Exception\FilterSetConfigurationNotFoundException; -use Lakion\SyliusElasticSearchBundle\Form\Configuration\Provider\FilterSetProviderInterface; -use Lakion\SyliusElasticSearchBundle\Form\DataMapper\CriteriaDataMapper; +use Sylius\ElasticSearchPlugin\Exception\FilterSetConfigurationNotFoundException; +use Sylius\ElasticSearchPlugin\Form\Configuration\Provider\FilterSetProviderInterface; +use Sylius\ElasticSearchPlugin\Form\DataMapper\CriteriaDataMapper; use Sylius\Bundle\ResourceBundle\Form\Registry\FormTypeRegistryInterface; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; diff --git a/src/Form/Type/OptionCodeFilterType.php b/src/Form/Type/OptionCodeFilterType.php index de43926..0705d8d 100644 --- a/src/Form/Type/OptionCodeFilterType.php +++ b/src/Form/Type/OptionCodeFilterType.php @@ -9,15 +9,15 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Form\Type; +namespace Sylius\ElasticSearchPlugin\Form\Type; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\EntityRepository; use FOS\ElasticaBundle\Manager\RepositoryManagerInterface; use FOS\ElasticaBundle\Repository; -use Lakion\SyliusElasticSearchBundle\Search\Criteria\Filtering\ProductHasOptionCodesFilter; -use Lakion\SyliusElasticSearchBundle\Search\Elastic\Factory\Query\QueryFactoryInterface; -use Lakion\SyliusElasticSearchBundle\Search\Elastic\Factory\Search\SearchFactoryInterface; +use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductHasOptionCodesFilter; +use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; +use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Search\SearchFactoryInterface; use ONGR\ElasticsearchDSL\Aggregation\FiltersAggregation; use ONGR\ElasticsearchDSL\Search; use Sylius\Component\Product\Model\ProductOptionValue; diff --git a/src/Form/Type/ProductPriceRangeFilterType.php b/src/Form/Type/ProductPriceRangeFilterType.php index 1d94ffc..c5ec27d 100644 --- a/src/Form/Type/ProductPriceRangeFilterType.php +++ b/src/Form/Type/ProductPriceRangeFilterType.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Form\Type; +namespace Sylius\ElasticSearchPlugin\Form\Type; -use Lakion\SyliusElasticSearchBundle\Search\Criteria\Filtering\ProductInPriceRangeFilter; +use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInPriceRangeFilter; use Sylius\Bundle\MoneyBundle\Form\Type\MoneyType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\DataTransformerInterface; diff --git a/src/Form/Type/SearchType.php b/src/Form/Type/SearchType.php index f69ee3f..c9ddd1b 100644 --- a/src/Form/Type/SearchType.php +++ b/src/Form/Type/SearchType.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Form\Type; +namespace Sylius\ElasticSearchPlugin\Form\Type; -use Lakion\SyliusElasticSearchBundle\Search\Criteria\SearchPhrase; +use Sylius\ElasticSearchPlugin\Search\Criteria\SearchPhrase; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\DataTransformerInterface; use Symfony\Component\Form\Extension\Core\Type\TextType; diff --git a/src/Resources/config/routing.yml b/src/Resources/config/routing.yml index d25146e..e69de29 100644 --- a/src/Resources/config/routing.yml +++ b/src/Resources/config/routing.yml @@ -1,34 +0,0 @@ -lakion_elastic_search_shop_product_index: - path: /products - methods: [GET] - defaults: - _controller: lakion_sylius_elastic_search.controller.search:filterAction - _sylius: - template: "@LakionSyliusElasticSearch/Product/index.html.twig" - resource_class: "%sylius.model.product.class%" - filter_set: mug_type_and_stickers_set - requirements: - slug: .+ - -lakion_elastic_search_shop_global_search: - path: /render-filter-set/{filterSetName} - methods: [GET] - defaults: - _controller: lakion_sylius_elastic_search.controller.search:renderFilterSetAction - _sylius: - template: "@LakionSyliusElasticSearch/Product/_globalSearch.html.twig" - resource_class: "%sylius.model.product.class%" - requirements: - slug: .+ - -sylius_shop_product_index: - path: /taxons/{slug} - methods: [GET] - defaults: - _controller: lakion_sylius_elastic_search.controller.search:filterByTaxonAction - _sylius: - template: "@LakionSyliusElasticSearch/Product/indexByTaxon.html.twig" - resource_class: "%sylius.model.product.class%" - filter_set: mug_type_and_stickers_set - requirements: - slug: .+ diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 5a64c6b..78ac814 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -13,7 +13,7 @@ - + diff --git a/src/Resources/config/services/controller.xml b/src/Resources/config/services/controller.xml index 9a6860b..922609c 100644 --- a/src/Resources/config/services/controller.xml +++ b/src/Resources/config/services/controller.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + diff --git a/src/Resources/config/services/filter_set_configuration_provider.xml b/src/Resources/config/services/filter_set_configuration_provider.xml index 1fc755c..3c0e931 100644 --- a/src/Resources/config/services/filter_set_configuration_provider.xml +++ b/src/Resources/config/services/filter_set_configuration_provider.xml @@ -5,10 +5,10 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + - + %lakion_sylius_elastic_search.filter_sets% diff --git a/src/Resources/config/services/form.xml b/src/Resources/config/services/form.xml index 4fa2ba7..46b1784 100644 --- a/src/Resources/config/services/form.xml +++ b/src/Resources/config/services/form.xml @@ -5,18 +5,18 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + - + - + @@ -24,7 +24,7 @@ - + diff --git a/src/Resources/config/services/query_factory.xml b/src/Resources/config/services/query_factory.xml index b4e02ea..753c8c2 100644 --- a/src/Resources/config/services/query_factory.xml +++ b/src/Resources/config/services/query_factory.xml @@ -5,13 +5,13 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - - - - - - + + + + + + + + diff --git a/src/Resources/config/services/search_criteria_applicator.xml b/src/Resources/config/services/search_criteria_applicator.xml index e266b71..93c86be 100644 --- a/src/Resources/config/services/search_criteria_applicator.xml +++ b/src/Resources/config/services/search_criteria_applicator.xml @@ -5,31 +5,31 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/src/Resources/config/services/search_engine.xml b/src/Resources/config/services/search_engine.xml index 9e4be62..9e96fcb 100644 --- a/src/Resources/config/services/search_engine.xml +++ b/src/Resources/config/services/search_engine.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + diff --git a/src/Resources/views/Product/_globalSearch.html.twig b/src/Resources/views/Product/_globalSearch.html.twig deleted file mode 100644 index 1999514..0000000 --- a/src/Resources/views/Product/_globalSearch.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -{{ form_start(form, { 'action': path('lakion_elastic_search_shop_product_index'), 'method': 'GET'}) }} -{{ form_rest(form) }} - -{{ form_end(form) }} diff --git a/src/Resources/views/Product/index.html.twig b/src/Resources/views/Product/index.html.twig deleted file mode 100644 index bdeec38..0000000 --- a/src/Resources/views/Product/index.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -{% extends '@SyliusShop/layout.html.twig' %} - -{% import '@SyliusUi/Macro/messages.html.twig' as messages %} - -{% block content %} -
-
- {{ form_start(form, {'method': 'GET'}) }} - - {{ form_row(form.search) }} - - {{ form_row(form) }} - - {{ form_end(form) }} -
-
- - {% if products|length > 0 %} -
- {% for product in products %} -
- {% include '@SyliusShop/Product/_box.html.twig' %} -
- {% endfor %} -
- - {% else %} - {{ messages.info('sylius.ui.no_results_to_display') }} - {% endif %} -
-
-{% endblock %} diff --git a/src/Resources/views/Product/indexByTaxon.html.twig b/src/Resources/views/Product/indexByTaxon.html.twig deleted file mode 100644 index c6d25a1..0000000 --- a/src/Resources/views/Product/indexByTaxon.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -{% extends '@SyliusShop/layout.html.twig' %} - -{% import '@SyliusUi/Macro/messages.html.twig' as messages %} - -{% block content %} - {% include '@SyliusShop/Product/Index/_header.html.twig' %} -
-
- {% include '@SyliusShop/Product/Index/_sidebar.html.twig' %} - {{ form_start(form, {'method' : 'GET'}) }} - - {{ form_rest(form) }} - - {{ form_end(form) }} -
-
- - {% if products|length > 0 %} -
- {% for product in products %} -
- {% include '@SyliusShop/Product/_box.html.twig' %} -
- {% endfor %} -
- - {% else %} - {{ messages.info('sylius.ui.no_results_to_display') }} - {% endif %} -
-
-{% endblock %} diff --git a/src/Search/Criteria/Criteria.php b/src/Search/Criteria/Criteria.php index defefae..d99bc44 100644 --- a/src/Search/Criteria/Criteria.php +++ b/src/Search/Criteria/Criteria.php @@ -1,6 +1,6 @@ diff --git a/src/Search/Criteria/Filtering.php b/src/Search/Criteria/Filtering.php index eb0baac..eac775e 100644 --- a/src/Search/Criteria/Filtering.php +++ b/src/Search/Criteria/Filtering.php @@ -1,6 +1,6 @@ diff --git a/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php b/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php index 845dab9..4d78d22 100644 --- a/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php +++ b/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Search\Criteria\Filtering; +namespace Sylius\ElasticSearchPlugin\Search\Criteria\Filtering; /** * @author Arkadiusz Krakowiak diff --git a/src/Search/Criteria/Filtering/ProductInChannelFilter.php b/src/Search/Criteria/Filtering/ProductInChannelFilter.php index b48f480..977b593 100644 --- a/src/Search/Criteria/Filtering/ProductInChannelFilter.php +++ b/src/Search/Criteria/Filtering/ProductInChannelFilter.php @@ -1,6 +1,6 @@ diff --git a/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php b/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php index 15e6ba2..4c5b4ed 100644 --- a/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php +++ b/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Search\Criteria\Filtering; +namespace Sylius\ElasticSearchPlugin\Search\Criteria\Filtering; /** * @author Arkadiusz Krakowiak diff --git a/src/Search/Criteria/Filtering/ProductInTaxonFilter.php b/src/Search/Criteria/Filtering/ProductInTaxonFilter.php index 0ed28f2..5509553 100644 --- a/src/Search/Criteria/Filtering/ProductInTaxonFilter.php +++ b/src/Search/Criteria/Filtering/ProductInTaxonFilter.php @@ -1,6 +1,6 @@ diff --git a/src/Search/Criteria/Ordering.php b/src/Search/Criteria/Ordering.php index e54e8a3..614d7d2 100644 --- a/src/Search/Criteria/Ordering.php +++ b/src/Search/Criteria/Ordering.php @@ -1,6 +1,6 @@ diff --git a/src/Search/Criteria/Paginating.php b/src/Search/Criteria/Paginating.php index 8b5917a..11b84f8 100644 --- a/src/Search/Criteria/Paginating.php +++ b/src/Search/Criteria/Paginating.php @@ -1,6 +1,6 @@ diff --git a/src/Search/Criteria/SearchPhrase.php b/src/Search/Criteria/SearchPhrase.php index 56f08b0..809c021 100644 --- a/src/Search/Criteria/SearchPhrase.php +++ b/src/Search/Criteria/SearchPhrase.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Search\Criteria; +namespace Sylius\ElasticSearchPlugin\Search\Criteria; /** * @author Arkadiusz Krakowiak diff --git a/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php index 2469e37..ed2720c 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php @@ -1,11 +1,11 @@ getCodes() as $code) { - $search->addFilter( + $search->addPostFilter( $this->productHasOptionCodeQueryFactory->create(['option_value_code' => $code]), BoolQuery::SHOULD ); diff --git a/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php index 127527e..603b4e2 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php @@ -1,11 +1,11 @@ addFilter($this->productInChannelQueryFactory->create(['channel_code' => $inChannelFilter->getChannelCode()]), BoolQuery::MUST); + $search->addPostFilter($this->productInChannelQueryFactory->create(['channel_code' => $inChannelFilter->getChannelCode()]), BoolQuery::MUST); } } diff --git a/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php index 0766e16..4882b01 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php @@ -1,11 +1,11 @@ addFilter( + $search->addPostFilter( $this->productInPriceRangeQueryFactory->create([ 'product_price_range' => [ 'grater_than' => $inPriceRangeFilter->getGraterThan(), diff --git a/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php index 6c86b1a..f3a0013 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php @@ -1,13 +1,11 @@ addFilter($this->productInMainTaxonQueryFactory->create(['taxon_code' => $inTaxonFilter->getTaxonCode()]), BoolQuery::SHOULD); - $search->addFilter($this->productInProductTaxonsQueryFactory->create(['taxon_code' => $inTaxonFilter->getTaxonCode()]), BoolQuery::SHOULD); + $search->addPostFilter($this->productInMainTaxonQueryFactory->create(['taxon_code' => $inTaxonFilter->getTaxonCode()]), BoolQuery::SHOULD); + $search->addPostFilter($this->productInProductTaxonsQueryFactory->create(['taxon_code' => $inTaxonFilter->getTaxonCode()]), BoolQuery::SHOULD); } } diff --git a/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php b/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php index af64fbd..fc4ca64 100644 --- a/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php +++ b/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php @@ -1,12 +1,10 @@ getPhrase()) { + $search->addQuery($this->matchProductNameQueryFactory->create(['phrase' => $searchPhrase->getPhrase()])); return; diff --git a/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php b/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php index 38723b9..a851665 100644 --- a/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php +++ b/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Search\Elastic\Applicator; +namespace Sylius\ElasticSearchPlugin\Search\Elastic\Applicator; use ONGR\ElasticsearchDSL\Search; diff --git a/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php b/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php index 2d5fa54..2ee484b 100644 --- a/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php +++ b/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php @@ -9,9 +9,8 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Search\Elastic\Applicator; +namespace Sylius\ElasticSearchPlugin\Search\Elastic\Applicator; -use Lakion\SyliusElasticSearchBundle\Search\Criteria\Criteria; use ONGR\ElasticsearchDSL\Search; /** diff --git a/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php b/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php index a448286..bb0e0d8 100644 --- a/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php +++ b/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php @@ -1,12 +1,10 @@ diff --git a/src/Search/Elastic/Factory/Query/EmptyCriteriaQueryFactory.php b/src/Search/Elastic/Factory/Query/EmptyCriteriaQueryFactory.php index affe87e..fd7b03d 100644 --- a/src/Search/Elastic/Factory/Query/EmptyCriteriaQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/EmptyCriteriaQueryFactory.php @@ -1,6 +1,6 @@ diff --git a/src/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactory.php index daa8f72..5f13d1b 100644 --- a/src/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactory.php @@ -1,10 +1,10 @@ diff --git a/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php index 6dd6422..08bf2a3 100644 --- a/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php @@ -1,10 +1,10 @@ diff --git a/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php index 152df5a..c3c0847 100644 --- a/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php @@ -1,9 +1,9 @@ diff --git a/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php index bc4b9f4..21243db 100644 --- a/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php @@ -1,10 +1,10 @@ diff --git a/src/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactory.php index 0673f32..108f98d 100644 --- a/src/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactory.php @@ -1,10 +1,10 @@ diff --git a/src/Search/Elastic/Factory/Query/QueryFactoryInterface.php b/src/Search/Elastic/Factory/Query/QueryFactoryInterface.php index 50cacbf..9f16de6 100644 --- a/src/Search/Elastic/Factory/Query/QueryFactoryInterface.php +++ b/src/Search/Elastic/Factory/Query/QueryFactoryInterface.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Lakion\SyliusElasticSearchBundle\Search\Elastic\Factory\Query; +namespace Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query; -use Lakion\SyliusElasticSearchBundle\Exception\MissingQueryParameterException; +use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; use ONGR\ElasticsearchDSL\BuilderInterface; /** diff --git a/src/Search/Elastic/Factory/Search/SearchFactory.php b/src/Search/Elastic/Factory/Search/SearchFactory.php index dea70e8..2fdb3fa 100644 --- a/src/Search/Elastic/Factory/Search/SearchFactory.php +++ b/src/Search/Elastic/Factory/Search/SearchFactory.php @@ -1,6 +1,6 @@ diff --git a/src/LakionSyliusElasticSearchBundle.php b/src/SyliusElasticSearchPlugin.php similarity index 53% rename from src/LakionSyliusElasticSearchBundle.php rename to src/SyliusElasticSearchPlugin.php index c9ffcb3..1c22d28 100644 --- a/src/LakionSyliusElasticSearchBundle.php +++ b/src/SyliusElasticSearchPlugin.php @@ -1,14 +1,17 @@ sharedStorage->get('search_result'); - Assert::eq($result->getTotalHits(), $numberOfProducts); + var_dump($result->getResults(1, 10)->toArray()); +// Assert::eq($result->getTotalHits, $numberOfProducts); } /** diff --git a/tests/Behat/Context/Hook/ElasticSearchContext.php b/tests/Behat/Context/Hook/ElasticSearchContext.php index 41a77dd..48cc7c2 100644 --- a/tests/Behat/Context/Hook/ElasticSearchContext.php +++ b/tests/Behat/Context/Hook/ElasticSearchContext.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Tests\Lakion\SyliusElasticSearchBundle\Behat\Context\Hook; +namespace Tests\Sylius\ElasticSearchPlugin\Behat\Context\Hook; use Behat\Behat\Context\Context; use FOS\ElasticaBundle\Index\Resetter; diff --git a/tests/Behat/Context/Setup/ProductContext.php b/tests/Behat/Context/Setup/ProductContext.php index dc874d4..511db2d 100644 --- a/tests/Behat/Context/Setup/ProductContext.php +++ b/tests/Behat/Context/Setup/ProductContext.php @@ -9,10 +9,10 @@ * file that was distributed with this source code. */ -namespace Tests\Lakion\SyliusElasticSearchBundle\Behat\Context\Setup; +namespace Tests\Sylius\ElasticSearchPlugin\Behat\Context\Setup; use Behat\Behat\Context\Context; -use Tests\Lakion\SyliusElasticSearchBundle\Behat\Services\SuspenderInterface; +use Tests\Sylius\ElasticSearchPlugin\Behat\Services\SuspenderInterface; use Sylius\Bundle\FixturesBundle\Fixture\FixtureInterface; /** diff --git a/tests/Behat/Context/Ui/Shop/ProductContext.php b/tests/Behat/Context/Ui/Shop/ProductContext.php deleted file mode 100644 index 3e20b58..0000000 --- a/tests/Behat/Context/Ui/Shop/ProductContext.php +++ /dev/null @@ -1,163 +0,0 @@ - - */ -final class ProductContext implements Context -{ - /** - * @var IndexPageInterface - */ - private $indexPage; - - /** - * @param IndexPageInterface $indexPage - */ - public function __construct(IndexPageInterface $indexPage) - { - $this->indexPage = $indexPage; - } - - /** - * @When I filter them by :mugTypeValue mug type - */ - public function iFilterThemByDoubleMugType($mugTypeValue) - { - $this->indexPage->open(); - $this->indexPage->setPaginating(100); - $this->indexPage->filterByProductOptions(Criteria::fromQueryParameters(Product::class, ['mug_type' => $mugTypeValue])); - $this->indexPage->filter(); - } - - /** - * @When I filter them by :mugTypeValue mug type or sticker size :stickerSizeValue - */ - public function iFilterThemByDoubleMugTypeAndStickerSize($mugTypeValue, $stickerSizeValue) - { - $this->indexPage->open(); - $this->indexPage->setPaginating(100); - $this->indexPage->filterByProductOptions(Criteria::fromQueryParameters(Product::class, ['mug_type' => $mugTypeValue, 'sticker_size' => $stickerSizeValue])); - $this->indexPage->filter(); - } - - /** - * @When I filter them by stickier size :stickerSizeValue - */ - public function iFilterThemByStickierSize($stickerSizeValue) - { - $this->indexPage->open(); - $this->indexPage->setPaginating(100); - $this->indexPage->filterByProductOptions(Criteria::fromQueryParameters(Product::class, ['sticker_size' => $stickerSizeValue])); - $this->indexPage->filter(); - } - - /** - * @When /^I filter them by price between ("[^"]+") and ("[^"]+")$/ - */ - public function iFilterThemByPriceBetweenAnd($graterThan, $lessThan) - { - sleep(3); - $this->indexPage->open(); - $this->indexPage->setPaginating(100); - $this->indexPage->filterByPriceRange($graterThan, $lessThan); - $this->indexPage->filter(); - } - - /** - * @When I search for products with name :name - */ - public function iSearchForProductsWithName($name) - { - sleep(3); - $this->indexPage->open(); - $this->indexPage->setPaginating(100); - $this->indexPage->search($name); - } - - /** - * @When I view the list of the products without filtering - */ - public function iViewTheListOfTheProductsWithoutFiltering() - { - $this->indexPage->open(['per_page' => 100]); - } - - /** - * @Then I should see :numberOfProducts products on the list - */ - public function iShouldSeeProductsOnTheList($numberOfProducts) - { - Assert::eq(count($this->indexPage->getAllProducts()), $numberOfProducts); - } - - /** - * @Then /^I should see products in order like "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)"$/ - */ - public function iShouldSeeProductsInOrderLike(...$productNames) - { - foreach ($this->indexPage->getAllProducts() as $position => $result) { - if ($result->getText() !== $productNames[$position]) { - throw new \RuntimeException( - sprintf( - 'Sorting failed at position "%s" expected value was "%s", but got "%s"', - $position+1, - $productNames[$position], - $result - ) - ); - } - } - } - - /** - * @Then /^It should be "([^"]+)"$/ - * @Then /^It should be "([^"]+)", "([^"]+)"$/ - * @Then /^It should be "([^"]+)", "([^"]+)", "([^"]+)"$/ - * @Then /^It should be "([^"]+)", "([^"]+)", "([^"]+)", "([^"]+)"$/ - */ - public function itShouldBe(...$expectedProductNames) - { - $resultProductNames = array_map(function (NodeElement $productElement) { - return $productElement->getText(); - }, $this->indexPage->getAllProducts()); - - $expectedProductCount = count($expectedProductNames); - $resultProductCount = count($resultProductNames); - - if ($expectedProductCount !== $resultProductCount) { - throw new \RuntimeException( - sprintf('Expected product count was "%s", got "%s"', $expectedProductCount, $resultProductCount) - ); - } - - foreach ($expectedProductNames as $expectedProductName) { - if (!in_array($expectedProductName, $resultProductNames)) { - throw new \RuntimeException(sprintf( - 'Expected product with name "%s", does not exist in search result. Got "%s"', - $expectedProductName, - implode(',', $resultProductNames) - )); - } - } - } -} diff --git a/tests/Behat/Page/Product/IndexPage.php b/tests/Behat/Page/Product/IndexPage.php deleted file mode 100644 index 3dd59b1..0000000 --- a/tests/Behat/Page/Product/IndexPage.php +++ /dev/null @@ -1,101 +0,0 @@ - - */ -final class IndexPage extends SymfonyPage implements IndexPageInterface -{ - /** - * {@inheritdoc} - */ - public function filterByProductOptions(Criteria $criteria) - { - foreach ($criteria->getFiltering()->getFields() as $type => $value) { - $filterType = $this->getElement('filter_option', [ - '%filter_type%' => $type, - '%filter_value%' => sprintf('%s_%s', $type, $value) - ]); - - $filterType->check(); - } - } - - /** - * {@inheritdoc} - */ - public function filterByPriceRange($graterThan, $lessThan) - { - $this->getElement('filter_price_range_grater_than')->setValue($graterThan / 100); - $this->getElement('filter_price_range_less_than')->setValue($lessThan / 100); - } - - public function filter() - { - $this->getDocument()->pressButton('Filter'); - } - - /** - * {@inheritdoc} - */ - public function setPaginating($perPage) - { - $this->getElement('pagination')->selectOption($perPage); - } - - /** - * {@inheritdoc} - */ - public function search($phrase) - { - $this->getElement('search')->setValue($phrase); - $this->getElement('search_submit')->press(); - } - - /** - * {@inheritdoc} - */ - public function getAllProducts() - { - $productElements = $this->getElement('products')->findAll('css', 'div .column > div .content > a'); - - return $productElements; - } - - /** - * {@inheritdoc} - */ - public function getRouteName() - { - return 'lakion_elastic_search_shop_product_index'; - } - - /** - * {@inheritdoc} - */ - protected function getDefinedElements() - { - return array_merge(parent::getDefinedElements(), [ - 'filter_option' => '#filter_set_%filter_type%_code_%filter_value%', - 'search' => '#filter_set_search', - 'search_submit' => '#search_submit', - 'filter_price_range_grater_than' => '#filter_set_product_price_grater_than', - 'filter_price_range_less_than' => '#filter_set_product_price_less_than', - 'products' => '#products', - 'pagination' => '#pagination', - ]); - } -} diff --git a/tests/Behat/Page/Product/IndexPageInterface.php b/tests/Behat/Page/Product/IndexPageInterface.php deleted file mode 100644 index b76abae..0000000 --- a/tests/Behat/Page/Product/IndexPageInterface.php +++ /dev/null @@ -1,50 +0,0 @@ - - */ -interface IndexPageInterface extends SymfonyPageInterface -{ - /** - * @param Criteria $criteria - */ - public function filterByProductOptions(Criteria $criteria); - - /** - * @param int $graterThan - * @param int $lessThan - */ - public function filterByPriceRange($graterThan, $lessThan); - - public function filter(); - - /** - * @param int $perPage - */ - public function setPaginating($perPage); - - /** - * @param $phrase - */ - public function search($phrase); - - /** - * @return NodeElement[] - */ - public function getAllProducts(); -} diff --git a/tests/Behat/Resources/services.xml b/tests/Behat/Resources/services.xml index 6f5df13..a8d1cd8 100644 --- a/tests/Behat/Resources/services.xml +++ b/tests/Behat/Resources/services.xml @@ -9,11 +9,11 @@ - + - + diff --git a/tests/Behat/Resources/services/searching_products.xml b/tests/Behat/Resources/services/searching_products.xml index 0a237bb..54ef50c 100644 --- a/tests/Behat/Resources/services/searching_products.xml +++ b/tests/Behat/Resources/services/searching_products.xml @@ -5,7 +5,7 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + @@ -13,17 +13,10 @@ - + - - - - - - - diff --git a/tests/Behat/Resources/suites.yml b/tests/Behat/Resources/suites.yml index fba5c5d..3ae4415 100644 --- a/tests/Behat/Resources/suites.yml +++ b/tests/Behat/Resources/suites.yml @@ -1,3 +1,2 @@ imports: - suites/shop/domain/product/searching_products.yml - - suites/shop/ui/product/searching_products.yml diff --git a/tests/Behat/Resources/suites/shop/ui/product/searching_products.yml b/tests/Behat/Resources/suites/shop/ui/product/searching_products.yml deleted file mode 100644 index 2ce1721..0000000 --- a/tests/Behat/Resources/suites/shop/ui/product/searching_products.yml +++ /dev/null @@ -1,19 +0,0 @@ -default: - suites: - ui_shop_searching_product: - contexts_services: - - lakion_sylius_elastic_search.behat.context.hook.elastic_search - - sylius.behat.context.hook.doctrine_orm - - - sylius.behat.context.transform.channel - - sylius.behat.context.transform.lexical - - sylius.behat.context.transform.taxon - - - lakion_sylius_elastic_search.behat.context.setup.product - - sylius.behat.context.setup.channel - - sylius.behat.context.setup.taxonomy - - sylius.behat.context.setup.product - - - lakion_sylius_elastic_search.behat.context.ui.shop.product - filters: - tags: "@searching_products && @ui" diff --git a/tests/Behat/Services/ElasticSearchSuspender.php b/tests/Behat/Services/ElasticSearchSuspender.php index eac2644..2603602 100644 --- a/tests/Behat/Services/ElasticSearchSuspender.php +++ b/tests/Behat/Services/ElasticSearchSuspender.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Tests\Lakion\SyliusElasticSearchBundle\Behat\Services; +namespace Tests\Sylius\ElasticSearchPlugin\Behat\Services; use Elastica\Client; use Elastica\Response; diff --git a/tests/Behat/Services/SuspenderInterface.php b/tests/Behat/Services/SuspenderInterface.php index 275cc99..88f7d74 100644 --- a/tests/Behat/Services/SuspenderInterface.php +++ b/tests/Behat/Services/SuspenderInterface.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace Tests\Lakion\SyliusElasticSearchBundle\Behat\Services; +namespace Tests\Sylius\ElasticSearchPlugin\Behat\Services; /** * @author Arkadiusz Krakowiak diff --git a/tests/DependencyInjection/Compiler/RegisterFilterTypePassTest.php b/tests/DependencyInjection/Compiler/RegisterFilterTypePassTest.php index 7464731..8bc7a1a 100644 --- a/tests/DependencyInjection/Compiler/RegisterFilterTypePassTest.php +++ b/tests/DependencyInjection/Compiler/RegisterFilterTypePassTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Tests\Lakion\SyliusElasticSearchBundle\DependencyInjection\Compiler; +namespace Tests\Sylius\ElasticSearchPlugin\DependencyInjection\Compiler; -use Lakion\SyliusElasticSearchBundle\DependencyInjection\Compiler\RegisterFilterTypePass; +use Sylius\ElasticSearchPlugin\DependencyInjection\Compiler\RegisterFilterTypePass; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\DefinitionHasMethodCallConstraint; use Symfony\Component\DependencyInjection\ContainerBuilder; diff --git a/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php b/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php index 5a086e5..b22043e 100644 --- a/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php +++ b/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Tests\Lakion\SyliusElasticSearchBundle\DependencyInjection\Compiler; +namespace Tests\Sylius\ElasticSearchPlugin\DependencyInjection\Compiler; -use Lakion\SyliusElasticSearchBundle\DependencyInjection\Compiler\RegisterSearchCriteriaApplicatorPass; +use Sylius\ElasticSearchPlugin\DependencyInjection\Compiler\RegisterSearchCriteriaApplicatorPass; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\DefinitionHasMethodCallConstraint; use Symfony\Component\DependencyInjection\ContainerBuilder; diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index ec3982d..caab2f3 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -9,9 +9,9 @@ * file that was distributed with this source code. */ -namespace Tests\Lakion\SyliusElasticSearchBundle\DependencyInjection; +namespace Tests\Sylius\ElasticSearchPlugin\DependencyInjection; -use Lakion\SyliusElasticSearchBundle\DependencyInjection\Configuration; +use Sylius\ElasticSearchPlugin\DependencyInjection\Configuration; use Matthias\SymfonyConfigTest\PhpUnit\ConfigurationTestCaseTrait; /** From 5763032487ed064763ff2f8748afd12d1bf60ac9 Mon Sep 17 00:00:00 2001 From: Arminek Date: Fri, 19 May 2017 04:08:59 +0200 Subject: [PATCH 2/6] [ElasticSearch] Remove foselasticsearch & rename namespaces & clean up --- .travis.yml | 3 +- README.md | 2 +- composer.json | 5 +- phpspec.yml.dist | 4 +- ...rSetConfigurationNotFoundExceptionSpec.php | 4 +- .../MissingQueryParameterExceptionSpec.php | 4 +- spec/Form/Configuration/FilterSetSpec.php | 6 +- spec/Form/Configuration/FilterSpec.php | 4 +- .../Provider/FilterSetProviderSpec.php | 10 +- .../FromArrayFilterSetProviderSpec.php | 10 +- spec/Search/Criteria/CriteriaSpec.php | 10 +- .../ProductHasOptionCodesFilterSpec.php | 4 +- .../Filtering/ProductInChannelFilterSpec.php | 4 +- .../ProductInPriceRangeFilterSpec.php | 4 +- .../Filtering/ProductInTaxonFilterSpec.php | 4 +- spec/Search/Criteria/FilteringSpec.php | 4 +- spec/Search/Criteria/OrderingSpec.php | 4 +- spec/Search/Criteria/PaginatingSpec.php | 4 +- spec/Search/Criteria/SearchPhraseSpec.php | 4 +- ...ctHasMultipleOptionCodesApplicatorSpec.php | 10 +- .../Filter/ProductInChannelApplicatorSpec.php | 10 +- .../ProductInPriceRangeApplicatorSpec.php | 10 +- .../Filter/ProductInTaxonApplicatorSpec.php | 12 +- .../MatchProductByNameApplicatorSpec.php | 12 +- .../Sort/SortByFieldApplicatorSpec.php | 12 +- .../Elastic/ElasticSearchEngineSpec.php | 16 +- .../Query/EmptyCriteriaQueryFactorySpec.php | 6 +- .../MatchProductNameQueryFactorySpec.php | 8 +- .../ProductHasOptionCodeQueryFactorySpec.php | 8 +- .../ProductInChannelQueryFactorySpec.php | 8 +- .../ProductInMainTaxonQueryFactorySpec.php | 8 +- .../ProductInPriceRangeQueryFactorySpec.php | 8 +- ...ProductInProductTaxonsQueryFactorySpec.php | 8 +- .../Factory/Search/SearchFactorySpec.php | 29 --- .../Sort/SortByFieldQueryFactorySpec.php | 8 +- src/Controller/SearchController.php | 2 +- .../Compiler/RegisterFilterTypePass.php | 6 +- .../RegisterSearchCriteriaApplicatorPass.php | 6 +- src/DependencyInjection/Configuration.php | 2 +- .../SyliusElasticSearchExtension.php | 2 +- ...ilterSetConfigurationNotFoundException.php | 2 +- .../MissingQueryParameterException.php | 2 +- src/Form/Configuration/Filter.php | 2 +- src/Form/Configuration/FilterSet.php | 2 +- .../Provider/FilterSetProvider.php | 2 +- .../Provider/FilterSetProviderInterface.php | 2 +- .../Provider/FromArrayFilterSetProvider.php | 2 +- src/Form/DataMapper/CriteriaDataMapper.php | 51 ------ src/Form/Type/FilterSetType.php | 82 --------- src/Form/Type/OptionCodeFilterType.php | 172 ------------------ src/Form/Type/ProductPriceRangeFilterType.php | 62 ------- src/Form/Type/SearchType.php | 66 ------- src/Resources/config/app/config.yml | 92 +--------- src/Resources/config/services.xml | 4 +- src/Resources/config/services/controller.xml | 4 +- .../filter_set_configuration_provider.xml | 4 +- src/Resources/config/services/form.xml | 32 ---- .../config/services/query_factory.xml | 16 +- .../services/search_criteria_applicator.xml | 28 +-- .../config/services/search_engine.xml | 5 +- src/Search/Criteria/Criteria.php | 2 +- src/Search/Criteria/Filtering.php | 2 +- .../Filtering/ProductHasOptionCodesFilter.php | 2 +- .../Filtering/ProductInChannelFilter.php | 2 +- .../Filtering/ProductInPriceRangeFilter.php | 2 +- .../Filtering/ProductInTaxonFilter.php | 2 +- src/Search/Criteria/Ordering.php | 2 +- src/Search/Criteria/Paginating.php | 2 +- src/Search/Criteria/SearchPhrase.php | 2 +- ...roductHasMultipleOptionCodesApplicator.php | 2 +- .../Filter/ProductInChannelApplicator.php | 2 +- .../Filter/ProductInPriceRangeApplicator.php | 2 +- .../Filter/ProductInTaxonApplicator.php | 2 +- .../Query/MatchProductByNameApplicator.php | 2 +- .../Applicator/SearchCriteriaApplicator.php | 2 +- .../SearchCriteriaApplicatorInterface.php | 2 +- .../Applicator/Sort/SortByFieldApplicator.php | 2 +- src/Search/Elastic/ElasticSearchEngine.php | 41 +---- .../Query/EmptyCriteriaQueryFactory.php | 2 +- .../Query/MatchProductNameQueryFactory.php | 2 +- .../ProductHasOptionCodeQueryFactory.php | 2 +- .../Query/ProductInChannelQueryFactory.php | 2 +- .../Query/ProductInMainTaxonQueryFactory.php | 2 +- .../Query/ProductInPriceRangeQueryFactory.php | 2 +- .../ProductInProductTaxonsQueryFactory.php | 2 +- .../Factory/Query/QueryFactoryInterface.php | 2 +- .../Elastic/Factory/Search/SearchFactory.php | 19 -- .../Factory/Search/SearchFactoryInterface.php | 25 --- .../Factory/Sort/SortByFieldQueryFactory.php | 2 +- .../Factory/Sort/SortFactoryInterface.php | 2 +- src/Search/SearchEngineInterface.php | 2 +- tests/Application/app/AppKernel.php | 2 +- .../Context/Hook/ElasticSearchContext.php | 42 ----- tests/Behat/Context/Setup/ProductContext.php | 44 ----- tests/Behat/Resources/services.xml | 10 - .../Resources/services/searching_products.xml | 10 +- .../domain/product/searching_products.yml | 5 +- .../Behat/Services/ElasticSearchSuspender.php | 58 ------ tests/Behat/Services/SuspenderInterface.php | 26 --- .../Compiler/RegisterFilterTypePassTest.php | 18 +- ...gisterSearchCriteriaApplicatorPassTest.php | 22 +-- 101 files changed, 233 insertions(+), 1062 deletions(-) delete mode 100644 spec/Search/Elastic/Factory/Search/SearchFactorySpec.php delete mode 100644 src/Form/DataMapper/CriteriaDataMapper.php delete mode 100644 src/Form/Type/FilterSetType.php delete mode 100644 src/Form/Type/OptionCodeFilterType.php delete mode 100644 src/Form/Type/ProductPriceRangeFilterType.php delete mode 100644 src/Form/Type/SearchType.php delete mode 100644 src/Resources/config/services/form.xml delete mode 100644 src/Search/Elastic/Factory/Search/SearchFactory.php delete mode 100644 src/Search/Elastic/Factory/Search/SearchFactoryInterface.php delete mode 100644 tests/Behat/Context/Hook/ElasticSearchContext.php delete mode 100644 tests/Behat/Services/ElasticSearchSuspender.php delete mode 100644 tests/Behat/Services/SuspenderInterface.php diff --git a/.travis.yml b/.travis.yml index 1ffb05b..385703c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,13 +2,12 @@ language: php php: - 7.1 - - 7.0 - 5.6 addons: apt: sources: - - elasticsearch-2.x + - elasticsearch-5.x packages: - elasticsearch diff --git a/README.md b/README.md index 3ba7e30..b312c52 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Elastic search for Sylius. 8. Configuration reference: ```yaml - lakion_sylius_elastic_search: + sylius_elastic_search: filter_sets: mugs: filters: diff --git a/composer.json b/composer.json index 5d033f3..2d0d11f 100644 --- a/composer.json +++ b/composer.json @@ -14,9 +14,8 @@ "php": "^5.6|^7.0", "sylius/sylius": "dev-master", - - "friendsofsymfony/elastica-bundle": "^4.0", - "ongr/elasticsearch-dsl": "^5.0" + "ongr/elasticsearch-dsl": "^5.0", + "ongr/elasticsearch-bundle": "^5.0" }, "require-dev": { "behat/behat": "^3.2", diff --git a/phpspec.yml.dist b/phpspec.yml.dist index ebc2561..681f57f 100644 --- a/phpspec.yml.dist +++ b/phpspec.yml.dist @@ -1,4 +1,4 @@ suites: default: - namespace: Lakion\SyliusElasticSearchBundle - psr4_prefix: Lakion\SyliusElasticSearchBundle + namespace: Sylius\ElasticSearchPlugin + psr4_prefix: Sylius\ElasticSearchPlugin diff --git a/spec/Exception/FilterSetConfigurationNotFoundExceptionSpec.php b/spec/Exception/FilterSetConfigurationNotFoundExceptionSpec.php index b4db631..648dabc 100644 --- a/spec/Exception/FilterSetConfigurationNotFoundExceptionSpec.php +++ b/spec/Exception/FilterSetConfigurationNotFoundExceptionSpec.php @@ -1,9 +1,9 @@ diff --git a/spec/Exception/MissingQueryParameterExceptionSpec.php b/spec/Exception/MissingQueryParameterExceptionSpec.php index c20a729..ca5bb5c 100644 --- a/spec/Exception/MissingQueryParameterExceptionSpec.php +++ b/spec/Exception/MissingQueryParameterExceptionSpec.php @@ -1,8 +1,8 @@ - */ -final class SearchFactorySpec extends ObjectBehavior -{ - function it_is_initializable() - { - $this->shouldHaveType(SearchFactory::class); - } - - function it_is_search_factory() - { - $this->shouldImplement(SearchFactoryInterface::class); - } - - function it_creates_new_empty_search_object() - { - $this->create()->shouldHaveType(Search::class); - } -} diff --git a/spec/Search/Elastic/Factory/Sort/SortByFieldQueryFactorySpec.php b/spec/Search/Elastic/Factory/Sort/SortByFieldQueryFactorySpec.php index 0a2e50b..c409667 100644 --- a/spec/Search/Elastic/Factory/Sort/SortByFieldQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Sort/SortByFieldQueryFactorySpec.php @@ -1,10 +1,10 @@ + * @author Arkadiusz Krakowiak */ final class SearchController { diff --git a/src/DependencyInjection/Compiler/RegisterFilterTypePass.php b/src/DependencyInjection/Compiler/RegisterFilterTypePass.php index bff7015..2609d7d 100644 --- a/src/DependencyInjection/Compiler/RegisterFilterTypePass.php +++ b/src/DependencyInjection/Compiler/RegisterFilterTypePass.php @@ -16,7 +16,7 @@ use Symfony\Component\DependencyInjection\Reference; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class RegisterFilterTypePass implements CompilerPassInterface { @@ -25,11 +25,11 @@ final class RegisterFilterTypePass implements CompilerPassInterface */ public function process(ContainerBuilder $container) { - if (!$container->hasDefinition('lakion_sylius_elastic_search.form_registry.filters')) { + if (!$container->hasDefinition('sylius_elastic_search.form_registry.filters')) { return; } - $registry = $container->getDefinition('lakion_sylius_elastic_search.form_registry.filters'); + $registry = $container->getDefinition('sylius_elastic_search.form_registry.filters'); foreach ($container->findTaggedServiceIds('filter.type') as $filterTypeServiceId => $filterTypeTag) { diff --git a/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php b/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php index 6a34660..0d27e1d 100644 --- a/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php +++ b/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php @@ -16,7 +16,7 @@ use Symfony\Component\DependencyInjection\Reference; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class RegisterSearchCriteriaApplicatorPass implements CompilerPassInterface { @@ -25,7 +25,7 @@ final class RegisterSearchCriteriaApplicatorPass implements CompilerPassInterfac */ public function process(ContainerBuilder $container) { - if (!$container->hasDefinition('lakion_sylius_elastic_search.search.elastic_engine')) { + if (!$container->hasDefinition('sylius_elastic_search.search.elastic_engine')) { return; } @@ -34,7 +34,7 @@ public function process(ContainerBuilder $container) throw new \InvalidArgumentException(sprintf('Applicator "%s" does not have applies attribute', $taggedServiceId)); } - $engineDefinition = $container->getDefinition('lakion_sylius_elastic_search.search.elastic_engine'); + $engineDefinition = $container->getDefinition('sylius_elastic_search.search.elastic_engine'); $engineDefinition->addMethodCall('addSearchCriteriaApplicator', [new Reference($taggedServiceId), $taggedServiceConfig[0]['applies']]); } } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index ec1373d..c9912b6 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -16,7 +16,7 @@ use Symfony\Component\Config\Definition\ConfigurationInterface; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class Configuration implements ConfigurationInterface { diff --git a/src/DependencyInjection/SyliusElasticSearchExtension.php b/src/DependencyInjection/SyliusElasticSearchExtension.php index 3869305..debba22 100644 --- a/src/DependencyInjection/SyliusElasticSearchExtension.php +++ b/src/DependencyInjection/SyliusElasticSearchExtension.php @@ -27,6 +27,6 @@ public function load(array $configs, ContainerBuilder $container) */ private function createFilterSetsParameter(array $config, ContainerBuilder $container) { - $container->setParameter('lakion_sylius_elastic_search.filter_sets', $config); + $container->setParameter('sylius_elastic_search.filter_sets', $config); } } diff --git a/src/Exception/FilterSetConfigurationNotFoundException.php b/src/Exception/FilterSetConfigurationNotFoundException.php index 80a5c21..81b4335 100644 --- a/src/Exception/FilterSetConfigurationNotFoundException.php +++ b/src/Exception/FilterSetConfigurationNotFoundException.php @@ -3,7 +3,7 @@ namespace Sylius\ElasticSearchPlugin\Exception; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class FilterSetConfigurationNotFoundException extends \RuntimeException { diff --git a/src/Exception/MissingQueryParameterException.php b/src/Exception/MissingQueryParameterException.php index 351b689..dc49b9f 100644 --- a/src/Exception/MissingQueryParameterException.php +++ b/src/Exception/MissingQueryParameterException.php @@ -12,7 +12,7 @@ namespace Sylius\ElasticSearchPlugin\Exception; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class MissingQueryParameterException extends \RuntimeException { diff --git a/src/Form/Configuration/Filter.php b/src/Form/Configuration/Filter.php index 058cfe1..44545ba 100644 --- a/src/Form/Configuration/Filter.php +++ b/src/Form/Configuration/Filter.php @@ -12,7 +12,7 @@ namespace Sylius\ElasticSearchPlugin\Form\Configuration; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class Filter { diff --git a/src/Form/Configuration/FilterSet.php b/src/Form/Configuration/FilterSet.php index 4379e91..de35680 100644 --- a/src/Form/Configuration/FilterSet.php +++ b/src/Form/Configuration/FilterSet.php @@ -12,7 +12,7 @@ namespace Sylius\ElasticSearchPlugin\Form\Configuration; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class FilterSet { diff --git a/src/Form/Configuration/Provider/FilterSetProvider.php b/src/Form/Configuration/Provider/FilterSetProvider.php index 84a48cd..d00aa27 100644 --- a/src/Form/Configuration/Provider/FilterSetProvider.php +++ b/src/Form/Configuration/Provider/FilterSetProvider.php @@ -6,7 +6,7 @@ use Zend\Stdlib\PriorityQueue; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class FilterSetProvider implements FilterSetProviderInterface { diff --git a/src/Form/Configuration/Provider/FilterSetProviderInterface.php b/src/Form/Configuration/Provider/FilterSetProviderInterface.php index 6e94bb1..c33cc80 100644 --- a/src/Form/Configuration/Provider/FilterSetProviderInterface.php +++ b/src/Form/Configuration/Provider/FilterSetProviderInterface.php @@ -15,7 +15,7 @@ use Sylius\ElasticSearchPlugin\Form\Configuration\FilterSet; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ interface FilterSetProviderInterface { diff --git a/src/Form/Configuration/Provider/FromArrayFilterSetProvider.php b/src/Form/Configuration/Provider/FromArrayFilterSetProvider.php index 107e46a..53299ed 100644 --- a/src/Form/Configuration/Provider/FromArrayFilterSetProvider.php +++ b/src/Form/Configuration/Provider/FromArrayFilterSetProvider.php @@ -15,7 +15,7 @@ use Sylius\ElasticSearchPlugin\Form\Configuration\FilterSet; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class FromArrayFilterSetProvider implements FilterSetProviderInterface { diff --git a/src/Form/DataMapper/CriteriaDataMapper.php b/src/Form/DataMapper/CriteriaDataMapper.php deleted file mode 100644 index 1ebee20..0000000 --- a/src/Form/DataMapper/CriteriaDataMapper.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ -final class CriteriaDataMapper implements DataMapperInterface -{ - /** - * {@inheritdoc} - */ - public function mapDataToForms($data, $forms) - { - } - - /** - * {@inheritdoc} - */ - public function mapFormsToData($forms, &$data) - { - $forms = iterator_to_array($forms); - $filtering = $data instanceof Criteria ? ['per_page' => $data->getPaginating()->getItemsPerPage()] : []; - - foreach ($forms as $form) { - if (null !== $form->getData()) { - $filtering[] = $form->getData(); - } - } - - $data = Criteria::fromQueryParameters( - $data->getResourceAlias(), - array_merge( - $filtering, - $data instanceof Criteria ? $data->getFiltering()->getFields() : [] - ) - ); - } -} diff --git a/src/Form/Type/FilterSetType.php b/src/Form/Type/FilterSetType.php deleted file mode 100644 index 8ee21a1..0000000 --- a/src/Form/Type/FilterSetType.php +++ /dev/null @@ -1,82 +0,0 @@ - - */ -final class FilterSetType extends AbstractType -{ - /** - * @var FormTypeRegistryInterface - */ - private $filterTypeRegistry; - - /** - * @var FilterSetProviderInterface - */ - private $filterSetConfigurationProvider; - - /** - * @param FormTypeRegistryInterface $filterTypeRegistry - * @param FilterSetProviderInterface $filterSetConfigurationProvider - */ - public function __construct( - FormTypeRegistryInterface $filterTypeRegistry, - FilterSetProviderInterface $filterSetConfigurationProvider - ) { - $this->filterTypeRegistry = $filterTypeRegistry; - $this->filterSetConfigurationProvider = $filterSetConfigurationProvider; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - try { - $filters = $this->filterSetConfigurationProvider->getFilterSetConfiguration($options['filter_set'])->getFilters(); - } catch (FilterSetConfigurationNotFoundException $configurationNotFoundException) { - $filters = $this->filterSetConfigurationProvider->getFilterSetConfiguration('default')->getFilters(); - } - - foreach ($filters as $filter) { - $builder->add( - $filter->getName(), - $this->filterTypeRegistry->get('default', $filter->getType()), - $filter->getOptions() - ); - } - - $builder->setDataMapper(new CriteriaDataMapper()); - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefault('csrf_protection', false) - ->setRequired('filter_set') - ->setAllowedTypes('filter_set', 'string') - ; - } -} diff --git a/src/Form/Type/OptionCodeFilterType.php b/src/Form/Type/OptionCodeFilterType.php deleted file mode 100644 index 0705d8d..0000000 --- a/src/Form/Type/OptionCodeFilterType.php +++ /dev/null @@ -1,172 +0,0 @@ - - */ -final class OptionCodeFilterType extends AbstractType implements DataTransformerInterface -{ - /** - * @var RepositoryManagerInterface - */ - private $repositoryManager; - - /** - * @var QueryFactoryInterface - */ - private $productHasOptionCodeQueryFactory; - - /** - * @var string - */ - private $productModelClass; - - /** - * @var SearchFactoryInterface - */ - private $searchFactory; - - /** - * @param RepositoryManagerInterface $repositoryManager - * @param QueryFactoryInterface $productHasOptionCodeQueryFactory - * @param SearchFactoryInterface $searchFactory - */ - public function __construct( - RepositoryManagerInterface $repositoryManager, - QueryFactoryInterface $productHasOptionCodeQueryFactory, - SearchFactoryInterface $searchFactory, - $productModelClass - ) { - $this->repositoryManager = $repositoryManager; - $this->productHasOptionCodeQueryFactory = $productHasOptionCodeQueryFactory; - $this->searchFactory = $searchFactory; - $this->productModelClass = $productModelClass; - } - - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder->add('code', EntityType::class, [ - 'class' => $options['class'], - 'choice_value' => function (ProductOptionValue $productOptionValue) { - return $productOptionValue->getCode(); - }, - 'query_builder' => function (EntityRepository $repository) use ($options) { - $queryBuilder = $repository->createQueryBuilder('o'); - - return $queryBuilder - ->leftJoin('o.option', 'option') - ->andWhere('option.code = :optionCode') - ->setParameter('optionCode', $options['option_code']); - }, - 'choice_label' => function (ProductOptionValue $productOptionValue) use ($options) { - - /** @var Repository $repository */ - $repository = $this->repositoryManager->getRepository($this->productModelClass); - $query = $this->buildAggregation($productOptionValue->getCode())->toArray(); - $result = $repository->createPaginatorAdapter($query); - $aggregation = $result->getAggregations(); - $count = $aggregation[$productOptionValue->getCode()]['buckets'][$productOptionValue->getCode()]['doc_count']; - - return sprintf('%s (%s)', $productOptionValue->getValue(), $count); - }, - 'multiple' => true, - 'expanded' => true, - ]); - - $builder->addModelTransformer($this); - } - - /** - * {@inheritdoc} - */ - public function transform($value) - { - if (null === $value) { - return null; - } - - return $value; - } - - /** - * {@inheritdoc} - */ - public function reverseTransform($value) - { - if ($value['code'] instanceof Collection) { - $productOptionCodes = $value['code']->map(function (ProductOptionValueInterface $productOptionValue) { - return $productOptionValue->getCode(); - }); - - if ($productOptionCodes->isEmpty()) { - return null; - } - - return new ProductHasOptionCodesFilter($productOptionCodes->toArray()); - } - - return null; - } - - /** - * {@inheritdoc} - */ - public function configureOptions(OptionsResolver $resolver) - { - $resolver - ->setDefault('class', ProductOptionValue::class) - ->setRequired('option_code') - ->setAllowedTypes('option_code', 'string') - ; - } - - /** - * @param string $code - * - * @return Search - */ - private function buildAggregation($code) - { - $hasOptionValueAggregation = new FiltersAggregation($code); - - $hasOptionValueAggregation->addFilter( - $this->productHasOptionCodeQueryFactory->create(['option_value_code' => $code]), - $code - ); - - $aggregationSearch = $this->searchFactory->create(); - $aggregationSearch->addAggregation($hasOptionValueAggregation); - - return $aggregationSearch; - } -} diff --git a/src/Form/Type/ProductPriceRangeFilterType.php b/src/Form/Type/ProductPriceRangeFilterType.php deleted file mode 100644 index c5ec27d..0000000 --- a/src/Form/Type/ProductPriceRangeFilterType.php +++ /dev/null @@ -1,62 +0,0 @@ - - */ -final class ProductPriceRangeFilterType extends AbstractType implements DataTransformerInterface -{ - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('grater_than', MoneyType::class) - ->add('less_than', MoneyType::class) - ->addModelTransformer($this) - ; - } - - /** - * {@inheritdoc} - */ - public function transform($value) - { - if (null === $value) { - return null; - } - - return $value; - } - - /** - * {@inheritdoc} - */ - public function reverseTransform($value) - { - if (null === $value['grater_than'] || null === $value['less_than']) { - return null; - } - - return new ProductInPriceRangeFilter($value['grater_than'], $value['less_than']); - } -} diff --git a/src/Form/Type/SearchType.php b/src/Form/Type/SearchType.php deleted file mode 100644 index c9ddd1b..0000000 --- a/src/Form/Type/SearchType.php +++ /dev/null @@ -1,66 +0,0 @@ - - */ -final class SearchType extends AbstractType implements DataTransformerInterface -{ - /** - * {@inheritdoc} - */ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->addModelTransformer($this) - ; - } - - /** - * {@inheritdoc} - */ - public function getParent() - { - return TextType::class; - } - - /** - * {@inheritdoc} - */ - public function transform($value) - { - if (null === $value) { - return null; - } - - return $value; - } - - /** - * {@inheritdoc} - */ - public function reverseTransform($value) - { - if (null === $value) { - return null; - } - - return new SearchPhrase($value); - } -} diff --git a/src/Resources/config/app/config.yml b/src/Resources/config/app/config.yml index 9474c28..cadf8d5 100644 --- a/src/Resources/config/app/config.yml +++ b/src/Resources/config/app/config.yml @@ -1,87 +1,7 @@ -fos_elastica: - clients: +ongr_elasticsearch: + managers: default: - servers: - - { host: 127.0.0.1, port: 9200 } - indexes: - sylius: - client: default - finder: ~ - settings: - analysis: - analyzer: - sylius_code_analyzer: - type: custom - tokenizer: whitespace - filter: [lowercase] - types: - product: - mappings: - id: { type: integer} - code: { type: string, analyzer: sylius_code_analyzer } - name: { type: string } - raw_name: { type: string, index: not_analyzed, property_path: name } - description: { type: string } - shortDescription: { type: string } - slug: { type: string } - translations: - type: "nested" - properties: - locale: { type: string } - name: { type: string } - metaKeywords: { type: string } - metaDescription: { type: string } - variants: - type: "nested" - properties: - code: { type: string } - name: { type: string } - onHand: { type: integer } - onHold: { type: integer } - channelPricings: - type: "nested" - properties: - price: { type: integer } - channelCode: { type: string } - optionValues: - type: "nested" - properties: - name: { type: string } - value: { type: string } - code: { type: string } - attributes: - type: "nested" - properties: - value: { type: string } - channels: - type: "nested" - properties: - code: { type: string, analyzer: sylius_code_analyzer } - productTaxons: - type: "nested" - properties: - taxon: - type: "object" - properties: - code: { type: string } - name: { type: string } - position: { type: integer } - mainTaxon: - type: "object" - properties: - slug: { type: string } - code: { type: string } - name: { type: string } - images: - type: "nested" - properties: - path: { type: string } - type: { type: string } - enabled: { type: boolean } - isSimple: { type: boolean } - persistence: - driver: orm - model: "%sylius.model.product.class%" - provider: ~ - listener: ~ - finder: ~ + index: + index_name: acme + mappings: + - SyliusElasticSearchPlugin diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 78ac814..baffc93 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -7,13 +7,11 @@ - - - + diff --git a/src/Resources/config/services/controller.xml b/src/Resources/config/services/controller.xml index 922609c..75272b8 100644 --- a/src/Resources/config/services/controller.xml +++ b/src/Resources/config/services/controller.xml @@ -5,9 +5,9 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + - + diff --git a/src/Resources/config/services/filter_set_configuration_provider.xml b/src/Resources/config/services/filter_set_configuration_provider.xml index 3c0e931..68df48b 100644 --- a/src/Resources/config/services/filter_set_configuration_provider.xml +++ b/src/Resources/config/services/filter_set_configuration_provider.xml @@ -5,11 +5,11 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + - %lakion_sylius_elastic_search.filter_sets% + %sylius_elastic_search.filter_sets% 1 diff --git a/src/Resources/config/services/form.xml b/src/Resources/config/services/form.xml deleted file mode 100644 index 46b1784..0000000 --- a/src/Resources/config/services/form.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - %sylius.model.product.class% - - - - - - - - - diff --git a/src/Resources/config/services/query_factory.xml b/src/Resources/config/services/query_factory.xml index 753c8c2..132a6ae 100644 --- a/src/Resources/config/services/query_factory.xml +++ b/src/Resources/config/services/query_factory.xml @@ -5,13 +5,13 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - - - - - - + + + + + + + + diff --git a/src/Resources/config/services/search_criteria_applicator.xml b/src/Resources/config/services/search_criteria_applicator.xml index 93c86be..a80f4c9 100644 --- a/src/Resources/config/services/search_criteria_applicator.xml +++ b/src/Resources/config/services/search_criteria_applicator.xml @@ -5,30 +5,30 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - + + - - - + + + - - + + - - + + - - + + - - - + + + diff --git a/src/Resources/config/services/search_engine.xml b/src/Resources/config/services/search_engine.xml index 9e96fcb..87cea50 100644 --- a/src/Resources/config/services/search_engine.xml +++ b/src/Resources/config/services/search_engine.xml @@ -5,9 +5,8 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - + + diff --git a/src/Search/Criteria/Criteria.php b/src/Search/Criteria/Criteria.php index d99bc44..ad4032a 100644 --- a/src/Search/Criteria/Criteria.php +++ b/src/Search/Criteria/Criteria.php @@ -3,7 +3,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Criteria; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class Criteria { diff --git a/src/Search/Criteria/Filtering.php b/src/Search/Criteria/Filtering.php index eac775e..f2480d9 100644 --- a/src/Search/Criteria/Filtering.php +++ b/src/Search/Criteria/Filtering.php @@ -3,7 +3,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Criteria; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class Filtering { diff --git a/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php b/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php index 4d78d22..8033095 100644 --- a/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php +++ b/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php @@ -12,7 +12,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Criteria\Filtering; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductHasOptionCodesFilter { diff --git a/src/Search/Criteria/Filtering/ProductInChannelFilter.php b/src/Search/Criteria/Filtering/ProductInChannelFilter.php index 977b593..699cc6f 100644 --- a/src/Search/Criteria/Filtering/ProductInChannelFilter.php +++ b/src/Search/Criteria/Filtering/ProductInChannelFilter.php @@ -3,7 +3,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Criteria\Filtering; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductInChannelFilter { diff --git a/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php b/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php index 4c5b4ed..b84a908 100644 --- a/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php +++ b/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php @@ -12,7 +12,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Criteria\Filtering; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductInPriceRangeFilter { diff --git a/src/Search/Criteria/Filtering/ProductInTaxonFilter.php b/src/Search/Criteria/Filtering/ProductInTaxonFilter.php index 5509553..ebb828d 100644 --- a/src/Search/Criteria/Filtering/ProductInTaxonFilter.php +++ b/src/Search/Criteria/Filtering/ProductInTaxonFilter.php @@ -3,7 +3,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Criteria\Filtering; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductInTaxonFilter { diff --git a/src/Search/Criteria/Ordering.php b/src/Search/Criteria/Ordering.php index 614d7d2..3a913a2 100644 --- a/src/Search/Criteria/Ordering.php +++ b/src/Search/Criteria/Ordering.php @@ -3,7 +3,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Criteria; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class Ordering { diff --git a/src/Search/Criteria/Paginating.php b/src/Search/Criteria/Paginating.php index 11b84f8..b5b66db 100644 --- a/src/Search/Criteria/Paginating.php +++ b/src/Search/Criteria/Paginating.php @@ -3,7 +3,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Criteria; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class Paginating { diff --git a/src/Search/Criteria/SearchPhrase.php b/src/Search/Criteria/SearchPhrase.php index 809c021..828d201 100644 --- a/src/Search/Criteria/SearchPhrase.php +++ b/src/Search/Criteria/SearchPhrase.php @@ -12,7 +12,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Criteria; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class SearchPhrase { diff --git a/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php index ed2720c..38efc25 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php @@ -9,7 +9,7 @@ use ONGR\ElasticsearchDSL\Search; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductHasMultipleOptionCodesApplicator extends SearchCriteriaApplicator { diff --git a/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php index 603b4e2..8a8978b 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php @@ -9,7 +9,7 @@ use ONGR\ElasticsearchDSL\Search; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductInChannelApplicator extends SearchCriteriaApplicator { diff --git a/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php index 4882b01..532ccd4 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php @@ -9,7 +9,7 @@ use ONGR\ElasticsearchDSL\Search; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductInPriceRangeApplicator extends SearchCriteriaApplicator { diff --git a/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php index f3a0013..dae5493 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php @@ -9,7 +9,7 @@ use ONGR\ElasticsearchDSL\Search; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductInTaxonApplicator extends SearchCriteriaApplicator { diff --git a/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php b/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php index fc4ca64..9bdb32f 100644 --- a/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php +++ b/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php @@ -8,7 +8,7 @@ use ONGR\ElasticsearchDSL\Search; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class MatchProductByNameApplicator extends SearchCriteriaApplicator { diff --git a/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php b/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php index a851665..ca507be 100644 --- a/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php +++ b/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php @@ -14,7 +14,7 @@ use ONGR\ElasticsearchDSL\Search; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ abstract class SearchCriteriaApplicator implements SearchCriteriaApplicatorInterface { diff --git a/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php b/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php index 2ee484b..4e80dcd 100644 --- a/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php +++ b/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php @@ -14,7 +14,7 @@ use ONGR\ElasticsearchDSL\Search; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ interface SearchCriteriaApplicatorInterface { diff --git a/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php b/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php index bb0e0d8..ca5d055 100644 --- a/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php +++ b/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php @@ -8,7 +8,7 @@ use ONGR\ElasticsearchDSL\Search; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class SortByFieldApplicator extends SearchCriteriaApplicator { diff --git a/src/Search/Elastic/ElasticSearchEngine.php b/src/Search/Elastic/ElasticSearchEngine.php index 1f5e86b..8f5d77e 100644 --- a/src/Search/Elastic/ElasticSearchEngine.php +++ b/src/Search/Elastic/ElasticSearchEngine.php @@ -2,27 +2,20 @@ namespace Sylius\ElasticSearchPlugin\Search\Elastic; -use FOS\ElasticaBundle\Manager\RepositoryManagerInterface; -use FOS\ElasticaBundle\Repository; +use ONGR\ElasticsearchBundle\Service\Manager; use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; -use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Search\SearchFactoryInterface; use Sylius\ElasticSearchPlugin\Search\SearchEngineInterface; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ElasticSearchEngine implements SearchEngineInterface { /** - * @var RepositoryManagerInterface + * @var Manager */ - private $repositoryManager; - - /** - * @var SearchFactoryInterface - */ - private $searchFactory; + private $manager; /** * @var SearchCriteriaApplicatorInterface[] @@ -30,13 +23,11 @@ final class ElasticSearchEngine implements SearchEngineInterface private $searchCriteriaApplicators = []; /** - * @param RepositoryManagerInterface $repositoryManager - * @param SearchFactoryInterface $searchFactory + * @param Manager $manager */ - public function __construct(RepositoryManagerInterface $repositoryManager, SearchFactoryInterface $searchFactory) + public function __construct(Manager $manager) { - $this->repositoryManager = $repositoryManager; - $this->searchFactory = $searchFactory; + $this->manager = $manager; } /** @@ -55,22 +46,10 @@ public function addSearchCriteriaApplicator( */ public function match(Criteria $criteria) { - $search = $this->searchFactory->create(); - $filters = array_merge($criteria->getFiltering()->getFields(), [$criteria->getOrdering()]); - - foreach ($filters as $filter) { - if (!is_object($filter)) { - continue; - } - - if (isset($this->searchCriteriaApplicators[get_class($filter)])) { - $this->searchCriteriaApplicators[get_class($filter)]->apply($filter, $search); - } - } + $repository = $this->manager->getRepository($criteria->getResourceAlias()); - /** @var Repository $repository */ - $repository = $this->repositoryManager->getRepository($criteria->getResourceAlias()); + $search = $repository->createSearch(); - return $repository->createPaginatorAdapter($search->toArray()); + return $repository->findDocuments($search); } } diff --git a/src/Search/Elastic/Factory/Query/EmptyCriteriaQueryFactory.php b/src/Search/Elastic/Factory/Query/EmptyCriteriaQueryFactory.php index fd7b03d..cc8b305 100644 --- a/src/Search/Elastic/Factory/Query/EmptyCriteriaQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/EmptyCriteriaQueryFactory.php @@ -5,7 +5,7 @@ use ONGR\ElasticsearchDSL\Query\MatchAllQuery; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class EmptyCriteriaQueryFactory implements QueryFactoryInterface { diff --git a/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php b/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php index bb7223d..20b2cc0 100644 --- a/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php @@ -7,7 +7,7 @@ use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class MatchProductNameQueryFactory implements QueryFactoryInterface { diff --git a/src/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactory.php index 5f13d1b..68787d1 100644 --- a/src/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactory.php @@ -7,7 +7,7 @@ use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductHasOptionCodeQueryFactory implements QueryFactoryInterface { diff --git a/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php index 08bf2a3..3a53382 100644 --- a/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php @@ -7,7 +7,7 @@ use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductInChannelQueryFactory implements QueryFactoryInterface { diff --git a/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php index c3c0847..1e0cfba 100644 --- a/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php @@ -6,7 +6,7 @@ use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductInMainTaxonQueryFactory implements QueryFactoryInterface { diff --git a/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php index 21243db..bc7e70f 100644 --- a/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php @@ -7,7 +7,7 @@ use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductInPriceRangeQueryFactory implements QueryFactoryInterface { diff --git a/src/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactory.php index 108f98d..3a44a4d 100644 --- a/src/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactory.php @@ -7,7 +7,7 @@ use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class ProductInProductTaxonsQueryFactory implements QueryFactoryInterface { diff --git a/src/Search/Elastic/Factory/Query/QueryFactoryInterface.php b/src/Search/Elastic/Factory/Query/QueryFactoryInterface.php index 9f16de6..7eb9ec6 100644 --- a/src/Search/Elastic/Factory/Query/QueryFactoryInterface.php +++ b/src/Search/Elastic/Factory/Query/QueryFactoryInterface.php @@ -15,7 +15,7 @@ use ONGR\ElasticsearchDSL\BuilderInterface; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ interface QueryFactoryInterface { diff --git a/src/Search/Elastic/Factory/Search/SearchFactory.php b/src/Search/Elastic/Factory/Search/SearchFactory.php deleted file mode 100644 index 2fdb3fa..0000000 --- a/src/Search/Elastic/Factory/Search/SearchFactory.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ -final class SearchFactory implements SearchFactoryInterface -{ - /** - * {@inheritdoc} - */ - public function create() - { - return new Search(); - } -} diff --git a/src/Search/Elastic/Factory/Search/SearchFactoryInterface.php b/src/Search/Elastic/Factory/Search/SearchFactoryInterface.php deleted file mode 100644 index 6ccd889..0000000 --- a/src/Search/Elastic/Factory/Search/SearchFactoryInterface.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ -interface SearchFactoryInterface -{ - /** - * @return Search - */ - public function create(); -} diff --git a/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php b/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php index c9090a5..fcb7598 100644 --- a/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php +++ b/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php @@ -6,7 +6,7 @@ use ONGR\ElasticsearchDSL\Sort\FieldSort; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ final class SortByFieldQueryFactory implements SortFactoryInterface { diff --git a/src/Search/Elastic/Factory/Sort/SortFactoryInterface.php b/src/Search/Elastic/Factory/Sort/SortFactoryInterface.php index 019e3e8..ddf069e 100644 --- a/src/Search/Elastic/Factory/Sort/SortFactoryInterface.php +++ b/src/Search/Elastic/Factory/Sort/SortFactoryInterface.php @@ -15,7 +15,7 @@ use ONGR\ElasticsearchDSL\BuilderInterface; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ interface SortFactoryInterface { diff --git a/src/Search/SearchEngineInterface.php b/src/Search/SearchEngineInterface.php index 5a9bb2b..b933ce9 100644 --- a/src/Search/SearchEngineInterface.php +++ b/src/Search/SearchEngineInterface.php @@ -15,7 +15,7 @@ use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; /** - * @author Arkadiusz Krakowiak + * @author Arkadiusz Krakowiak */ interface SearchEngineInterface { diff --git a/tests/Application/app/AppKernel.php b/tests/Application/app/AppKernel.php index bb54589..1abd685 100644 --- a/tests/Application/app/AppKernel.php +++ b/tests/Application/app/AppKernel.php @@ -18,7 +18,7 @@ public function registerBundles() new \FOS\OAuthServerBundle\FOSOAuthServerBundle(), // Required by SyliusAdminApiBundle new \Sylius\Bundle\AdminApiBundle\SyliusAdminApiBundle(), - new \FOS\ElasticaBundle\FOSElasticaBundle(), + new \ONGR\ElasticsearchBundle\ONGRElasticsearchBundle(), ]); } diff --git a/tests/Behat/Context/Hook/ElasticSearchContext.php b/tests/Behat/Context/Hook/ElasticSearchContext.php deleted file mode 100644 index 48cc7c2..0000000 --- a/tests/Behat/Context/Hook/ElasticSearchContext.php +++ /dev/null @@ -1,42 +0,0 @@ - - */ -final class ElasticSearchContext implements Context -{ - /** - * @var Resetter - */ - private $resetter; - - /** - * @param Resetter $resetter - */ - public function __construct(Resetter $resetter) - { - $this->resetter = $resetter; - } - - /** - * @BeforeScenario - */ - public function resetElasticSearch() - { - $this->resetter->resetAllIndexes(); - } -} diff --git a/tests/Behat/Context/Setup/ProductContext.php b/tests/Behat/Context/Setup/ProductContext.php index 511db2d..d0ab8ab 100644 --- a/tests/Behat/Context/Setup/ProductContext.php +++ b/tests/Behat/Context/Setup/ProductContext.php @@ -12,61 +12,17 @@ namespace Tests\Sylius\ElasticSearchPlugin\Behat\Context\Setup; use Behat\Behat\Context\Context; -use Tests\Sylius\ElasticSearchPlugin\Behat\Services\SuspenderInterface; -use Sylius\Bundle\FixturesBundle\Fixture\FixtureInterface; /** * @author Arkadiusz Krakowiak */ final class ProductContext implements Context { - /** - * @var FixtureInterface - */ - private $bookProductFixture; - - /** - * @var FixtureInterface - */ - private $mugProductFixture; - - /** - * @var FixtureInterface - */ - private $stickerProductFixture; - - /** - * @var SuspenderInterface - */ - private $elasticSearchSuspender; - - /** - * @param FixtureInterface $bookProductFixture - * @param FixtureInterface $mugProductFixture - * @param FixtureInterface $stickerProductFixture - * @param SuspenderInterface $elasticSearchSuspender - */ - public function __construct( - FixtureInterface $bookProductFixture, - FixtureInterface $mugProductFixture, - FixtureInterface $stickerProductFixture, - SuspenderInterface $elasticSearchSuspender - ) { - $this->bookProductFixture = $bookProductFixture; - $this->mugProductFixture = $mugProductFixture; - $this->stickerProductFixture = $stickerProductFixture; - $this->elasticSearchSuspender = $elasticSearchSuspender; - } - /** * @Given the store has :mugsNumber Mugs, :stickersNumber Stickers and :booksNumber Books */ public function theStoreHasAboutMugsAndStickers($mugsNumber, $stickersNumber, $booksNumber) { - $this->mugProductFixture->load(['amount' => (int) $mugsNumber]); - $this->stickerProductFixture->load(['amount' => (int) $stickersNumber]); - $this->bookProductFixture->load(['amount' => (int) $booksNumber]); - $this->elasticSearchSuspender->waitForLoadingNumberOfData((int) $mugsNumber + (int) $stickersNumber + (int) $booksNumber, 5); } } diff --git a/tests/Behat/Resources/services.xml b/tests/Behat/Resources/services.xml index a8d1cd8..755b7a1 100644 --- a/tests/Behat/Resources/services.xml +++ b/tests/Behat/Resources/services.xml @@ -7,14 +7,4 @@ - - - - - - - - - - diff --git a/tests/Behat/Resources/services/searching_products.xml b/tests/Behat/Resources/services/searching_products.xml index 54ef50c..57a04f2 100644 --- a/tests/Behat/Resources/services/searching_products.xml +++ b/tests/Behat/Resources/services/searching_products.xml @@ -5,16 +5,12 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - - - + - - + + diff --git a/tests/Behat/Resources/suites/shop/domain/product/searching_products.yml b/tests/Behat/Resources/suites/shop/domain/product/searching_products.yml index 4850d05..abcc117 100644 --- a/tests/Behat/Resources/suites/shop/domain/product/searching_products.yml +++ b/tests/Behat/Resources/suites/shop/domain/product/searching_products.yml @@ -2,18 +2,17 @@ default: suites: domain_shop_searching_product: contexts_services: - - lakion_sylius_elastic_search.behat.context.hook.elastic_search - sylius.behat.context.hook.doctrine_orm - sylius.behat.context.transform.channel - sylius.behat.context.transform.lexical - sylius.behat.context.transform.taxon - - lakion_sylius_elastic_search.behat.context.setup.product + - sylius_elastic_search.behat.context.setup.product - sylius.behat.context.setup.channel - sylius.behat.context.setup.taxonomy - sylius.behat.context.setup.product - - lakion_sylius_elastic_search.behat.context.domain.shop.product + - sylius_elastic_search.behat.context.domain.shop.product filters: tags: "@searching_products && @domain" diff --git a/tests/Behat/Services/ElasticSearchSuspender.php b/tests/Behat/Services/ElasticSearchSuspender.php deleted file mode 100644 index 2603602..0000000 --- a/tests/Behat/Services/ElasticSearchSuspender.php +++ /dev/null @@ -1,58 +0,0 @@ - - */ -final class ElasticSearchSuspender implements SuspenderInterface -{ - /** - * @var Client - */ - private $client; - - /** - * @param Client $client - */ - public function __construct(Client $client) - { - $this->client = $client; - } - - /** - * {@inheritdoc} - */ - public function waitForLoadingNumberOfData($number, $timeoutSeconds) - { - $start = microtime(true); - $end = $start + $timeoutSeconds; - - do { - $response = $this->refreshResponse(); - $count = !isset($response->getData()['count']) ? 0 : $response->getData()['count']; - - sleep(1); - } while ($count !== $number && microtime(true) < $end); - } - - /** - * @return Response - */ - private function refreshResponse() - { - return $this->client->request('_count'); - } -} diff --git a/tests/Behat/Services/SuspenderInterface.php b/tests/Behat/Services/SuspenderInterface.php deleted file mode 100644 index 88f7d74..0000000 --- a/tests/Behat/Services/SuspenderInterface.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ -interface SuspenderInterface -{ - /** - * @param int $number - * @param int $timeoutSeconds - * - * @return bool - */ - public function waitForLoadingNumberOfData($number, $timeoutSeconds); -} diff --git a/tests/DependencyInjection/Compiler/RegisterFilterTypePassTest.php b/tests/DependencyInjection/Compiler/RegisterFilterTypePassTest.php index 8bc7a1a..1a9fdd0 100644 --- a/tests/DependencyInjection/Compiler/RegisterFilterTypePassTest.php +++ b/tests/DependencyInjection/Compiler/RegisterFilterTypePassTest.php @@ -28,16 +28,16 @@ final class RegisterFilterTypePassTest extends AbstractCompilerPassTestCase */ public function it_collects_tagged_filter_types() { - $this->setDefinition('lakion_sylius_elastic_search.form_registry.filters', new Definition()); + $this->setDefinition('sylius_elastic_search.form_registry.filters', new Definition()); $this->setDefinition( - 'lakion_sylius_elastic_search.form_type.filter', + 'sylius_elastic_search.form_type.filter', (new Definition(\stdClass::class))->addTag('form.type')->addTag('filter.type', ['type' => 'option']) ); $this->compile(); $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( - 'lakion_sylius_elastic_search.form_registry.filters', + 'sylius_elastic_search.form_registry.filters', 'add', ['default', 'option', \stdClass::class] ); @@ -50,7 +50,7 @@ public function it_does_nothing_if_there_is_no_filter_registry() { $this->compile(); - $this->assertContainerBuilderNotHasService('lakion_sylius_elastic_search.form_registry.filters'); + $this->assertContainerBuilderNotHasService('sylius_elastic_search.form_registry.filters'); } /** @@ -58,16 +58,16 @@ public function it_does_nothing_if_there_is_no_filter_registry() */ public function it_does_nothing_if_there_is_no_tagged_filters() { - $this->setDefinition('lakion_sylius_elastic_search.form_registry.filters', new Definition()); + $this->setDefinition('sylius_elastic_search.form_registry.filters', new Definition()); $this->setDefinition( - 'lakion_sylius_elastic_search.form_type.filter', + 'sylius_elastic_search.form_type.filter', (new Definition())->addTag('tag', ['type' => 'option']) ); $this->compile(); $this->assertContainerBuilderNotHasServiceDefinitionWithMethodCall( - 'lakion_sylius_elastic_search.form_registry.filters', + 'sylius_elastic_search.form_registry.filters', 'add', ['default', 'option', 'class'] ); @@ -78,9 +78,9 @@ public function it_does_nothing_if_there_is_no_tagged_filters() */ public function tagged_filter_types_must_have_type_configured() { - $this->setDefinition('lakion_sylius_elastic_search.form_registry.filters', new Definition()); + $this->setDefinition('sylius_elastic_search.form_registry.filters', new Definition()); $this->setDefinition( - 'lakion_sylius_elastic_search.form_type.filter', + 'sylius_elastic_search.form_type.filter', (new Definition())->addTag('form.type')->addTag('filter.type') ); diff --git a/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php b/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php index b22043e..dd6ecb6 100644 --- a/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php +++ b/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php @@ -28,19 +28,19 @@ final class RegisterSearchCriteriaApplicatorPassTest extends AbstractCompilerPas */ public function it_collects_tagged_search_criteria_applicators() { - $this->setDefinition('lakion_sylius_elastic_search.search.elastic_engine', new Definition()); + $this->setDefinition('sylius_elastic_search.search.elastic_engine', new Definition()); $this->setDefinition( - 'lakion_sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes', + 'sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes', (new Definition(\stdClass::class))->addTag('search_criteria_applicator', ['applies' => 'productHasOption']) ); $this->compile(); $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( - 'lakion_sylius_elastic_search.search.elastic_engine', + 'sylius_elastic_search.search.elastic_engine', 'addSearchCriteriaApplicator', [ - new Reference('lakion_sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes'), + new Reference('sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes'), 'productHasOption' ] ); @@ -53,7 +53,7 @@ public function it_does_nothing_if_there_is_no_search_criteria_applicators() { $this->compile(); - $this->assertContainerBuilderNotHasService('lakion_sylius_elastic_search.search.elastic_engine'); + $this->assertContainerBuilderNotHasService('sylius_elastic_search.search.elastic_engine'); } /** @@ -61,9 +61,9 @@ public function it_does_nothing_if_there_is_no_search_criteria_applicators() */ public function tagged_applicators_must_have_applies_attribute_configured() { - $this->setDefinition('lakion_sylius_elastic_search.search.elastic_engine', new Definition()); + $this->setDefinition('sylius_elastic_search.search.elastic_engine', new Definition()); $this->setDefinition( - 'lakion_sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes', + 'sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes', (new Definition(\stdClass::class))->addTag('search_criteria_applicator') ); @@ -76,18 +76,18 @@ public function tagged_applicators_must_have_applies_attribute_configured() */ public function it_does_nothing_if_there_is_no_tagged_applicators() { - $this->setDefinition('lakion_sylius_elastic_search.search.elastic_engine', new Definition()); + $this->setDefinition('sylius_elastic_search.search.elastic_engine', new Definition()); $this->setDefinition( - 'lakion_sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes', + 'sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes', new Definition(\stdClass::class) ); $this->compile(); $this->assertContainerBuilderNotHasServiceDefinitionWithMethodCall( - 'lakion_sylius_elastic_search.search.elastic_engine', + 'sylius_elastic_search.search.elastic_engine', 'addSearchCriteriaApplicator', - [new Reference('lakion_sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes')] + [new Reference('sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes')] ); } From 8279230140e2f2920afc917961cd70416893fc34 Mon Sep 17 00:00:00 2001 From: Arminek Date: Fri, 19 May 2017 08:41:37 +0200 Subject: [PATCH 3/6] [ElasticSearch] Create product read model && configure its mapping && adjust filter applicators --- spec/Document/AttributeSpec.php | 28 +++ spec/Document/PriceSpec.php | 28 +++ spec/Document/ProductSpec.php | 73 ++++++ ...ctHasMultipleOptionCodesApplicatorSpec.php | 10 +- .../Filter/ProductInChannelApplicatorSpec.php | 6 +- .../ProductInPriceRangeApplicatorSpec.php | 10 +- .../Filter/ProductInTaxonApplicatorSpec.php | 16 +- .../MatchProductByNameApplicatorSpec.php | 3 +- .../Sort/SortByFieldApplicatorSpec.php | 1 - .../Elastic/ElasticSearchEngineSpec.php | 134 ----------- .../MatchProductNameQueryFactorySpec.php | 5 +- .../ProductHasOptionCodeQueryFactorySpec.php | 4 +- .../ProductInChannelQueryFactorySpec.php | 7 +- .../ProductInMainTaxonQueryFactorySpec.php | 4 +- .../ProductInPriceRangeQueryFactorySpec.php | 11 +- ...ProductInProductTaxonsQueryFactorySpec.php | 4 +- src/Controller/SearchController.php | 10 - src/Document/Attribute.php | 80 +++++++ src/Document/Price.php | 57 +++++ src/Document/Product.php | 224 ++++++++++++++++++ src/Resources/config/app/config.yml | 2 +- .../Filter/ProductInTaxonApplicator.php | 14 +- src/Search/Elastic/ElasticSearchEngine.php | 10 + .../Query/MatchProductNameQueryFactory.php | 2 +- .../Query/ProductInChannelQueryFactory.php | 2 +- .../Query/ProductInMainTaxonQueryFactory.php | 2 +- .../Query/ProductInPriceRangeQueryFactory.php | 8 +- src/Search/SearchEngineInterface.php | 4 +- 28 files changed, 540 insertions(+), 219 deletions(-) create mode 100644 spec/Document/AttributeSpec.php create mode 100644 spec/Document/PriceSpec.php create mode 100644 spec/Document/ProductSpec.php delete mode 100644 spec/Search/Elastic/ElasticSearchEngineSpec.php create mode 100644 src/Document/Attribute.php create mode 100644 src/Document/Price.php create mode 100644 src/Document/Product.php diff --git a/spec/Document/AttributeSpec.php b/spec/Document/AttributeSpec.php new file mode 100644 index 0000000..28a87bc --- /dev/null +++ b/spec/Document/AttributeSpec.php @@ -0,0 +1,28 @@ +shouldHaveType(Attribute::class); + } + + function it_has_value() + { + $this->setValue('red'); + + $this->getValue()->shouldReturn('red'); + } + + function it_has_name() + { + $this->setName('color'); + + $this->getName()->shouldReturn('color'); + } +} diff --git a/spec/Document/PriceSpec.php b/spec/Document/PriceSpec.php new file mode 100644 index 0000000..42d64f5 --- /dev/null +++ b/spec/Document/PriceSpec.php @@ -0,0 +1,28 @@ +shouldHaveType(Price::class); + } + + function it_has_amount() + { + $this->setAmount(1000); + + $this->getAmount()->shouldReturn(1000); + } + + function it_has_currency() + { + $this->setCurrency('EUR'); + + $this->getCurrency()->shouldReturn('EUR'); + } +} diff --git a/spec/Document/ProductSpec.php b/spec/Document/ProductSpec.php new file mode 100644 index 0000000..f78fbb4 --- /dev/null +++ b/spec/Document/ProductSpec.php @@ -0,0 +1,73 @@ +shouldHaveType(Product::class); + } + + function it_has_code() + { + $this->setCode('Mug'); + + $this->getCode()->shouldReturn('Mug'); + } + + function it_has_name() + { + $this->setName('Big Mug'); + + $this->getName()->shouldReturn('Big Mug'); + } + + function it_has_channel_code() + { + $this->setChannelCode('WEB'); + + $this->getChannelCode()->shouldReturn('WEB'); + } + + function it_has_locale_code() + { + $this->setLocaleCode('en'); + + $this->getLocaleCode()->shouldReturn('en'); + } + + function it_has_description() + { + $this->setDescription('Lorem ipsum'); + + $this->getDescription()->shouldReturn('Lorem ipsum'); + } + + function it_has_price() + { + $this->setPrice(1000); + + $this->getPrice()->shouldReturn(1000); + } + + function it_has_taxon_code() + { + $this->setTaxonCode('Tree'); + + $this->getTaxonCode()->shouldReturn('Tree'); + } + + function it_has_attributes() + { + $attributes = new ArrayCollection([new Attribute()]); + $this->setAttributes($attributes); + + $this->getAttributes()->shouldReturn($attributes); + } +} diff --git a/spec/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicatorSpec.php b/spec/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicatorSpec.php index 679d99a..3e87e91 100644 --- a/spec/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicatorSpec.php @@ -2,12 +2,12 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter; +use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; +use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery; use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductHasOptionCodesFilter; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter\ProductHasMultipleOptionCodesApplicator; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; -use ONGR\ElasticsearchDSL\Query\BoolQuery; -use ONGR\ElasticsearchDSL\Query\TermQuery; use ONGR\ElasticsearchDSL\Search; use PhpSpec\ObjectBehavior; @@ -41,8 +41,8 @@ function it_applies_search_query_for_multiple_product_options( $productHasOptionCodeQueryFactory->create(['option_value_code' => 'medium_mug'])->willReturn($mediumMugTermQuery); $productHasOptionCodeQueryFactory->create(['option_value_code' => 'sticker_size_1'])->willReturn($stickerSizeTermQuery); - $search->addFilter($mediumMugTermQuery, BoolQuery::SHOULD)->shouldBeCalled(); - $search->addFilter($stickerSizeTermQuery, BoolQuery::SHOULD)->shouldBeCalled(); + $search->addPostFilter($mediumMugTermQuery, BoolQuery::SHOULD)->shouldBeCalled(); + $search->addPostFilter($stickerSizeTermQuery, BoolQuery::SHOULD)->shouldBeCalled(); $this->apply($criteria, $search); } @@ -55,7 +55,7 @@ function it_applies_search_query_for_single_product_option( $criteria = new ProductHasOptionCodesFilter(['medium_mug']); $productHasOptionCodeQueryFactory->create(['option_value_code' => 'medium_mug'])->willReturn($mediumMugTermQuery); - $search->addFilter($mediumMugTermQuery, BoolQuery::SHOULD)->shouldBeCalled(); + $search->addPostFilter($mediumMugTermQuery, BoolQuery::SHOULD)->shouldBeCalled(); $this->apply($criteria, $search); } diff --git a/spec/Search/Elastic/Applicator/Filter/ProductInChannelApplicatorSpec.php b/spec/Search/Elastic/Applicator/Filter/ProductInChannelApplicatorSpec.php index 4a50c28..0a5c868 100644 --- a/spec/Search/Elastic/Applicator/Filter/ProductInChannelApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Filter/ProductInChannelApplicatorSpec.php @@ -2,12 +2,12 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter; +use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; +use ONGR\ElasticsearchDSL\Query\Joining\NestedQuery; use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInChannelFilter; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter\ProductInChannelApplicator; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; -use ONGR\ElasticsearchDSL\Query\BoolQuery; -use ONGR\ElasticsearchDSL\Query\NestedQuery; use ONGR\ElasticsearchDSL\Search; use PhpSpec\ObjectBehavior; @@ -38,7 +38,7 @@ function it_applies_search_criteria_with_channel_code( ) { $criteria = new ProductInChannelFilter('web'); $productInChannelQueryFactory->create(['channel_code' => 'web'])->willReturn($nestedQuery); - $search->addFilter($nestedQuery, BoolQuery::MUST)->shouldBeCalled(); + $search->addPostFilter($nestedQuery, BoolQuery::MUST)->shouldBeCalled(); $this->apply($criteria, $search); } diff --git a/spec/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicatorSpec.php b/spec/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicatorSpec.php index 76988e9..46011c9 100644 --- a/spec/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicatorSpec.php @@ -2,12 +2,12 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter; +use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; +use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery; use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInPriceRangeFilter; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter\ProductInPriceRangeApplicator; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; -use ONGR\ElasticsearchDSL\Query\BoolQuery; -use ONGR\ElasticsearchDSL\Query\NestedQuery; use ONGR\ElasticsearchDSL\Search; use PhpSpec\ObjectBehavior; @@ -31,11 +31,11 @@ function it_is_search_criteria_applicator() $this->shouldImplement(SearchCriteriaApplicatorInterface::class); } - function it_applies_search_criteria_for_given_query(QueryFactoryInterface $productInPriceRangeQueryFactory, Search $search, NestedQuery $nestedQuery) + function it_applies_search_criteria_for_given_query(QueryFactoryInterface $productInPriceRangeQueryFactory, Search $search, TermQuery $termQuery) { $criteria = new ProductInPriceRangeFilter(20, 50); - $productInPriceRangeQueryFactory->create(['product_price_range' => ['grater_than' => 20, 'less_than' => 50]])->willReturn($nestedQuery); - $search->addFilter($nestedQuery, BoolQuery::MUST)->shouldBeCalled(); + $productInPriceRangeQueryFactory->create(['product_price_range' => ['grater_than' => 20, 'less_than' => 50]])->willReturn($termQuery); + $search->addPostFilter($termQuery, BoolQuery::MUST)->shouldBeCalled(); $this->apply($criteria, $search); } diff --git a/spec/Search/Elastic/Applicator/Filter/ProductInTaxonApplicatorSpec.php b/spec/Search/Elastic/Applicator/Filter/ProductInTaxonApplicatorSpec.php index 930aec6..a4e7439 100644 --- a/spec/Search/Elastic/Applicator/Filter/ProductInTaxonApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Filter/ProductInTaxonApplicatorSpec.php @@ -2,14 +2,12 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter; -use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; +use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; +use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery; use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInTaxonFilter; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter\ProductInTaxonApplicator; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; -use ONGR\ElasticsearchDSL\Query\BoolQuery; -use ONGR\ElasticsearchDSL\Query\NestedQuery; -use ONGR\ElasticsearchDSL\Query\TermQuery; use ONGR\ElasticsearchDSL\Search; use PhpSpec\ObjectBehavior; @@ -18,9 +16,9 @@ */ final class ProductInTaxonApplicatorSpec extends ObjectBehavior { - function let(QueryFactoryInterface $productInMainTaxon, QueryFactoryInterface $productInProductTaxons) + function let(QueryFactoryInterface $productInMainTaxon) { - $this->beConstructedWith($productInMainTaxon, $productInProductTaxons); + $this->beConstructedWith($productInMainTaxon); } function it_is_initializable() @@ -35,18 +33,14 @@ function it_is_search_criteria_applicator() function it_applies_search_query_for_given_criteria( QueryFactoryInterface $productInMainTaxon, - QueryFactoryInterface $productInProductTaxons, - NestedQuery $nestedQuery, TermQuery $termQuery, Search $search ) { $criteria = new ProductInTaxonFilter('mugs'); $productInMainTaxon->create(['taxon_code' => 'mugs'])->willReturn($termQuery); - $productInProductTaxons->create(['taxon_code' => 'mugs'])->willReturn($nestedQuery); - $search->addFilter($termQuery, BoolQuery::SHOULD)->shouldBeCalled(); - $search->addFilter($nestedQuery, BoolQuery::SHOULD)->shouldBeCalled(); + $search->addPostFilter($termQuery, BoolQuery::SHOULD)->shouldBeCalled(); $this->apply($criteria, $search); } diff --git a/spec/Search/Elastic/Applicator/Query/MatchProductByNameApplicatorSpec.php b/spec/Search/Elastic/Applicator/Query/MatchProductByNameApplicatorSpec.php index bc5bdf1..3b0356f 100644 --- a/spec/Search/Elastic/Applicator/Query/MatchProductByNameApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Query/MatchProductByNameApplicatorSpec.php @@ -2,13 +2,12 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Query; -use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; +use ONGR\ElasticsearchDSL\Query\FullText\MatchQuery; use Sylius\ElasticSearchPlugin\Search\Criteria\SearchPhrase; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Query\MatchProductByNameApplicator; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; use ONGR\ElasticsearchDSL\Query\MatchAllQuery; -use ONGR\ElasticsearchDSL\Query\MatchQuery; use ONGR\ElasticsearchDSL\Search; use PhpSpec\ObjectBehavior; diff --git a/spec/Search/Elastic/Applicator/Sort/SortByFieldApplicatorSpec.php b/spec/Search/Elastic/Applicator/Sort/SortByFieldApplicatorSpec.php index 86f6964..ba69640 100644 --- a/spec/Search/Elastic/Applicator/Sort/SortByFieldApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Sort/SortByFieldApplicatorSpec.php @@ -2,7 +2,6 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Sort; -use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\Criteria\Ordering; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Sort\SortByFieldApplicator; diff --git a/spec/Search/Elastic/ElasticSearchEngineSpec.php b/spec/Search/Elastic/ElasticSearchEngineSpec.php deleted file mode 100644 index 7a885e6..0000000 --- a/spec/Search/Elastic/ElasticSearchEngineSpec.php +++ /dev/null @@ -1,134 +0,0 @@ - - */ -final class ElasticSearchEngineSpec extends ObjectBehavior -{ - function let(RepositoryManagerInterface $repositoryManager, SearchFactoryInterface $searchFactory) - { - $this->beConstructedWith($repositoryManager, $searchFactory); - } - - function it_is_initializable() - { - $this->shouldHaveType(ElasticSearchEngine::class); - } - - function it_is_search_engine() - { - $this->shouldImplement(SearchEngineInterface::class); - } - - function it_returns_paginator_with_default_query_if_there_is_no_applicators_registered( - RepositoryManagerInterface $repositoryManager, - SearchFactoryInterface $searchFactory, - Search $search, - Repository $repository, - SearchCriteriaApplicatorInterface $orderingApplicator, - PaginatorAdapterInterface $paginatorAdapter - ) { - $criteria = Criteria::fromQueryParameters('product', []); - $searchFactory->create()->willReturn($search); - $repositoryManager->getRepository('product')->willReturn($repository); - - $this->addSearchCriteriaApplicator($orderingApplicator, Ordering::class); - $orderingApplicator->apply($criteria->getOrdering(), $search)->shouldBeCalled(); - - $search->toArray()->willReturn([ - 'query' => [ - 'match_all' => new \stdClass(), - ] - ]); - - $repository->createPaginatorAdapter([ - 'query' => [ - 'match_all' => new \stdClass(), - ] - ])->willReturn($paginatorAdapter); - - $this->match($criteria)->shouldReturn($paginatorAdapter); - } - - function it_returns_resources_based_on_applicators_which_supports_given_criteria( - RepositoryManagerInterface $repositoryManager, - SearchFactoryInterface $searchFactory, - Search $search, - Repository $repository, - PaginatorAdapterInterface $paginatorAdapter, - SearchCriteriaApplicatorInterface $productHasOptionCodesApplicator, - SearchCriteriaApplicatorInterface $orderingApplicator - ) { - $productHasOptionCodesFilter = new ProductHasOptionCodesFilter(['mug_type']); - $criteria = Criteria::fromQueryParameters('product', [$productHasOptionCodesFilter]); - $this->addSearchCriteriaApplicator($productHasOptionCodesApplicator, ProductHasOptionCodesFilter::class); - $this->addSearchCriteriaApplicator($orderingApplicator, Ordering::class); - $searchFactory->create()->willReturn($search); - - $productHasOptionCodesApplicator->apply($productHasOptionCodesFilter, $search)->shouldBeCalled(); - $orderingApplicator->apply($criteria->getOrdering(), $search)->shouldBeCalled(); - - $repositoryManager->getRepository('product')->willReturn($repository); - $search->toArray()->willReturn([ - 'query' => [ - 'match_all' => new \stdClass(), - ] - ]); - - $repository->createPaginatorAdapter([ - 'query' => [ - 'match_all' => new \stdClass(), - ] - ])->willReturn($paginatorAdapter); - - $this->match($criteria)->shouldReturn($paginatorAdapter); - } - - function it_does_not_apply_none_object_filter( - RepositoryManagerInterface $repositoryManager, - SearchFactoryInterface $searchFactory, - Search $search, - Repository $repository, - PaginatorAdapterInterface $paginatorAdapter, - SearchCriteriaApplicatorInterface $productHasOptionCodesApplicator, - SearchCriteriaApplicatorInterface $orderingApplicator - ) { - $criteria = Criteria::fromQueryParameters('product', [null]); - $this->addSearchCriteriaApplicator($productHasOptionCodesApplicator, ProductHasOptionCodesFilter::class); - $this->addSearchCriteriaApplicator($orderingApplicator, Ordering::class); - $searchFactory->create()->willReturn($search); - - $productHasOptionCodesApplicator->apply(null, $search)->shouldNotBeCalled(); - $orderingApplicator->apply($criteria->getOrdering(), $search)->shouldBeCalled(); - - $repositoryManager->getRepository('product')->willReturn($repository); - $search->toArray()->willReturn([ - 'query' => [ - 'match_all' => new \stdClass(), - ] - ]); - - $repository->createPaginatorAdapter([ - 'query' => [ - 'match_all' => new \stdClass(), - ] - ])->willReturn($paginatorAdapter); - - $this->match($criteria)->shouldReturn($paginatorAdapter); - } -} diff --git a/spec/Search/Elastic/Factory/Query/MatchProductNameQueryFactorySpec.php b/spec/Search/Elastic/Factory/Query/MatchProductNameQueryFactorySpec.php index 7498477..77200bd 100644 --- a/spec/Search/Elastic/Factory/Query/MatchProductNameQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Query/MatchProductNameQueryFactorySpec.php @@ -2,11 +2,10 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query; +use ONGR\ElasticsearchDSL\Query\FullText\MatchQuery; use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\MatchProductNameQueryFactory; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; -use ONGR\ElasticsearchDSL\Query\MatchQuery; -use ONGR\ElasticsearchDSL\Query\NestedQuery; use PhpSpec\ObjectBehavior; /** @@ -26,7 +25,7 @@ function it_is_query_factory() function it_creates_match_query_with_name_field_by_default() { - $this->create(['phrase' => 'banana'])->shouldBeLike(new NestedQuery('translations', new MatchQuery('translations.name', 'banana'))); + $this->create(['phrase' => 'banana'])->shouldBeLike(new MatchQuery('name', 'banana')); } function it_cannot_be_created_without_search_parameter() diff --git a/spec/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactorySpec.php b/spec/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactorySpec.php index 3a58e24..a548152 100644 --- a/spec/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Query/ProductHasOptionCodeQueryFactorySpec.php @@ -2,11 +2,11 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query; +use ONGR\ElasticsearchDSL\Query\Joining\NestedQuery; +use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery; use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\ProductHasOptionCodeQueryFactory; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; -use ONGR\ElasticsearchDSL\Query\NestedQuery; -use ONGR\ElasticsearchDSL\Query\TermQuery; use PhpSpec\ObjectBehavior; /** diff --git a/spec/Search/Elastic/Factory/Query/ProductInChannelQueryFactorySpec.php b/spec/Search/Elastic/Factory/Query/ProductInChannelQueryFactorySpec.php index 3c6b648..a11d233 100644 --- a/spec/Search/Elastic/Factory/Query/ProductInChannelQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Query/ProductInChannelQueryFactorySpec.php @@ -2,11 +2,10 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query; +use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery; use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\ProductInChannelQueryFactory; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; -use ONGR\ElasticsearchDSL\Query\NestedQuery; -use ONGR\ElasticsearchDSL\Query\TermQuery; use PhpSpec\ObjectBehavior; /** @@ -26,9 +25,7 @@ function it_is_query_factory() function it_creates_product_in_channel_query() { - $this->create(['channel_code' => 'web'])->shouldBeLike( - new NestedQuery('channels', new TermQuery('channels.code', 'web')) - ); + $this->create(['channel_code' => 'web'])->shouldBeLike(new TermQuery('channelCode', 'web')); } function it_cannot_be_created_without_channel_code() diff --git a/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php b/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php index 96a91ce..1ad1a9f 100644 --- a/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php @@ -2,10 +2,10 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query; +use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery; use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\ProductInMainTaxonQueryFactory; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; -use ONGR\ElasticsearchDSL\Query\TermQuery; use PhpSpec\ObjectBehavior; /** @@ -25,7 +25,7 @@ function it_is_query_factory() function it_creates_query() { - $this->create(['taxon_code' => 'mugs'])->shouldBeLike(new TermQuery('mainTaxon.code', 'mugs')); + $this->create(['taxon_code' => 'mugs'])->shouldBeLike(new TermQuery('taxonCode', 'mugs')); } function it_cannot_create_query_if_there_is_no_required_parameters() diff --git a/spec/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactorySpec.php b/spec/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactorySpec.php index a486118..95db118 100644 --- a/spec/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactorySpec.php @@ -2,11 +2,10 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query; +use ONGR\ElasticsearchDSL\Query\TermLevel\RangeQuery; use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\ProductInPriceRangeQueryFactory; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; -use ONGR\ElasticsearchDSL\Query\NestedQuery; -use ONGR\ElasticsearchDSL\Query\RangeQuery; use PhpSpec\ObjectBehavior; /** @@ -27,13 +26,7 @@ function it_is_query_factory() function it_creates_price_range_query_for_products() { $this->create(['product_price_range' => ['grater_than' => 1000, 'less_than' => 2000]]) - ->shouldBeLike( - new NestedQuery('variants', - new NestedQuery('variants.channelPricings', - new RangeQuery('variants.channelPricings.price', ['gte' => 1000, 'lte' => 2000]) - ) - ) - ); + ->shouldBeLike(new RangeQuery('price.amount', ['gte' => 1000, 'lte' => 2000])); } function it_cannot_be_created_without_price_range_parameters() diff --git a/spec/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactorySpec.php b/spec/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactorySpec.php index c7cfa28..9d6e279 100644 --- a/spec/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Query/ProductInProductTaxonsQueryFactorySpec.php @@ -2,11 +2,11 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query; +use ONGR\ElasticsearchDSL\Query\Joining\NestedQuery; +use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery; use Sylius\ElasticSearchPlugin\Exception\MissingQueryParameterException; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\ProductInProductTaxonsQueryFactory; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; -use ONGR\ElasticsearchDSL\Query\NestedQuery; -use ONGR\ElasticsearchDSL\Query\TermQuery; use PhpSpec\ObjectBehavior; /** diff --git a/src/Controller/SearchController.php b/src/Controller/SearchController.php index a77c2e5..40e09e1 100644 --- a/src/Controller/SearchController.php +++ b/src/Controller/SearchController.php @@ -12,18 +12,8 @@ namespace Sylius\ElasticSearchPlugin\Controller; use FOS\RestBundle\View\ConfigurableViewHandlerInterface; -use FOS\RestBundle\View\View; -use Sylius\ElasticSearchPlugin\Form\Type\FilterSetType; -use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; -use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInChannelFilter; -use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInTaxonFilter; use Sylius\ElasticSearchPlugin\Search\SearchEngineInterface; -use Sylius\Component\Core\Context\ShopperContextInterface; -use Sylius\Component\Taxonomy\Repository\TaxonRepositoryInterface; -use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\HttpException; /** * @author Arkadiusz Krakowiak diff --git a/src/Document/Attribute.php b/src/Document/Attribute.php new file mode 100644 index 0000000..13a324a --- /dev/null +++ b/src/Document/Attribute.php @@ -0,0 +1,80 @@ +code; + } + + /** + * @param string $code + */ + public function setCode($code) + { + $this->code = $code; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * @param string $value + */ + public function setValue($value) + { + $this->value = $value; + } +} diff --git a/src/Document/Price.php b/src/Document/Price.php new file mode 100644 index 0000000..da1763d --- /dev/null +++ b/src/Document/Price.php @@ -0,0 +1,57 @@ +amount = $amount; + } + + /** + * @param string $currency + */ + public function setCurrency($currency) + { + $this->currency = $currency; + } + + /** + * @return int + */ + public function getAmount() + { + return $this->amount; + } + + /** + * @return string + */ + public function getCurrency() + { + return $this->currency; + } +} diff --git a/src/Document/Product.php b/src/Document/Product.php new file mode 100644 index 0000000..4b28795 --- /dev/null +++ b/src/Document/Product.php @@ -0,0 +1,224 @@ +attributes = new ArrayCollection(); + } + + /** + * @return string + */ + public function getCode() + { + return $this->code; + } + + /** + * @param string $code + */ + public function setCode($code) + { + $this->code = $code; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * @return string + */ + public function getChannelCode() + { + return $this->channelCode; + } + + /** + * @param string $channelCode + */ + public function setChannelCode($channelCode) + { + $this->channelCode = $channelCode; + } + + /** + * @return string + */ + public function getLocaleCode() + { + return $this->localeCode; + } + + /** + * @param string $localeCode + */ + public function setLocaleCode($localeCode) + { + $this->localeCode = $localeCode; + } + + /** + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * @param string $description + */ + public function setDescription($description) + { + $this->description = $description; + } + + /** + * @return int + */ + public function getPrice() + { + return $this->price; + } + + /** + * @param int $price + */ + public function setPrice($price) + { + $this->price = $price; + } + + /** + * @return string + */ + public function getTaxonCode() + { + return $this->taxonCode; + } + + /** + * @param string $taxonCode + */ + public function setTaxonCode($taxonCode) + { + $this->taxonCode = $taxonCode; + } + + /** + * @return ArrayCollection + */ + public function getAttributes() + { + return $this->attributes; + } + + /** + * @param ArrayCollection $attributes + */ + public function setAttributes(ArrayCollection $attributes) + { + $this->attributes = $attributes; + } + + /** + * @return \DateTime + */ + public function getCreatedAt() + { + return $this->createdAt; + } + + /** + * @param \DateTime $createdAt + */ + public function setCreatedAt(\DateTime $createdAt) + { + $this->createdAt = $createdAt; + } +} diff --git a/src/Resources/config/app/config.yml b/src/Resources/config/app/config.yml index cadf8d5..856662a 100644 --- a/src/Resources/config/app/config.yml +++ b/src/Resources/config/app/config.yml @@ -2,6 +2,6 @@ ongr_elasticsearch: managers: default: index: - index_name: acme + index_name: sylius mappings: - SyliusElasticSearchPlugin diff --git a/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php index dae5493..315ec02 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php @@ -18,21 +18,12 @@ final class ProductInTaxonApplicator extends SearchCriteriaApplicator */ private $productInMainTaxonQueryFactory; - /** - * @var QueryFactoryInterface - */ - private $productInProductTaxonsQueryFactory; - /** * @param QueryFactoryInterface $productInMainTaxonQueryFactory - * @param QueryFactoryInterface $productInProductTaxonsQueryFactory */ - public function __construct( - QueryFactoryInterface $productInMainTaxonQueryFactory, - QueryFactoryInterface $productInProductTaxonsQueryFactory - ) { + public function __construct(QueryFactoryInterface $productInMainTaxonQueryFactory) + { $this->productInMainTaxonQueryFactory = $productInMainTaxonQueryFactory; - $this->productInProductTaxonsQueryFactory = $productInProductTaxonsQueryFactory; } /** @@ -41,6 +32,5 @@ public function __construct( public function applyProductInTaxonFilter(ProductInTaxonFilter $inTaxonFilter, Search $search) { $search->addPostFilter($this->productInMainTaxonQueryFactory->create(['taxon_code' => $inTaxonFilter->getTaxonCode()]), BoolQuery::SHOULD); - $search->addPostFilter($this->productInProductTaxonsQueryFactory->create(['taxon_code' => $inTaxonFilter->getTaxonCode()]), BoolQuery::SHOULD); } } diff --git a/src/Search/Elastic/ElasticSearchEngine.php b/src/Search/Elastic/ElasticSearchEngine.php index 8f5d77e..1a90def 100644 --- a/src/Search/Elastic/ElasticSearchEngine.php +++ b/src/Search/Elastic/ElasticSearchEngine.php @@ -50,6 +50,16 @@ public function match(Criteria $criteria) $search = $repository->createSearch(); + foreach ($this->searchCriteriaApplicators as $filter => $searchCriteriaApplicator) { + if (!is_object($filter)) { + continue; + } + + if (isset($this->searchCriteriaApplicators[get_class($filter)])) { + $this->searchCriteriaApplicators[get_class($filter)]->apply($filter, $search); + } + } + return $repository->findDocuments($search); } } diff --git a/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php b/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php index 20b2cc0..d52b9a9 100644 --- a/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php @@ -20,6 +20,6 @@ public function create(array $parameters = []) throw new MissingQueryParameterException('search', get_class($this)); } - return new NestedQuery('translations', new MatchQuery('translations.name', $parameters['phrase'])); + return new MatchQuery('name', $parameters['phrase']); } } diff --git a/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php index 3a53382..fe01b9d 100644 --- a/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php @@ -20,6 +20,6 @@ public function create(array $parameters = []) throw new MissingQueryParameterException('channel_code', get_class($this)); } - return new NestedQuery('channels', new TermQuery('channels.code', strtolower($parameters['channel_code']))); + return new TermQuery('channelCode', strtolower($parameters['channel_code'])); } } diff --git a/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php index 1e0cfba..f4afbbf 100644 --- a/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php @@ -19,6 +19,6 @@ public function create(array $parameters = []) throw new MissingQueryParameterException('taxon_code', get_class($this)); } - return new TermQuery('mainTaxon.code', strtolower($parameters['taxon_code'])); + return new TermQuery('taxonCode', strtolower($parameters['taxon_code'])); } } diff --git a/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php index bc7e70f..4a48bd3 100644 --- a/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInPriceRangeQueryFactory.php @@ -21,13 +21,7 @@ public function create(array $parameters = []) $graterThan = $parameters['product_price_range']['grater_than']; $lessThan = $parameters['product_price_range']['less_than']; - return new NestedQuery( - 'variants', - new NestedQuery( - 'variants.channelPricings', - new RangeQuery('variants.channelPricings.price', ['gte' => $graterThan, 'lte' => $lessThan]) - ) - ); + return new RangeQuery('price.amount', ['gte' => $graterThan, 'lte' => $lessThan]); } /** diff --git a/src/Search/SearchEngineInterface.php b/src/Search/SearchEngineInterface.php index b933ce9..ce0d20e 100644 --- a/src/Search/SearchEngineInterface.php +++ b/src/Search/SearchEngineInterface.php @@ -11,7 +11,7 @@ namespace Sylius\ElasticSearchPlugin\Search; -use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface; +use ONGR\ElasticsearchBundle\Result\DocumentIterator; use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; /** @@ -22,7 +22,7 @@ interface SearchEngineInterface /** * @param Criteria $criteria * - * @return PaginatorAdapterInterface + * @return DocumentIterator */ public function match(Criteria $criteria); } From 7713de04c3f6ab8a86239aa0d7aae3ae4e9256e7 Mon Sep 17 00:00:00 2001 From: Arminek Date: Tue, 23 May 2017 10:54:29 +0200 Subject: [PATCH 4/6] [ElasticSearch] Adjust es configuration && tweak ElasticSearchEngine --- .travis.yml | 6 +- composer.json | 3 +- ...tering_list_of_products_by_channel.feature | 15 ++-- ...tering_list_of_products_by_options.feature | 29 ------- ...ng_list_of_products_by_price_range.feature | 3 +- ...roducts_by_price_range_and_channel.feature | 15 ++-- ...iltering_list_of_products_by_taxon.feature | 9 +-- .../searching_products_by_name.feature | 3 +- .../sorting_list_of_products_by_name.feature | 15 ++-- spec/Document/ProductSpec.php | 11 +-- spec/Search/Criteria/FilteringSpec.php | 2 +- spec/Search/Criteria/OrderingSpec.php | 4 +- spec/Search/Criteria/PaginatingSpec.php | 4 +- .../ProductInChannelQueryFactorySpec.php | 2 +- .../ProductInMainTaxonQueryFactorySpec.php | 2 +- .../Sort/SortByFieldQueryFactorySpec.php | 6 +- .../SyliusElasticSearchExtension.php | 11 +-- src/Document/Attribute.php | 4 +- src/Document/Price.php | 24 +++--- src/Document/Product.php | 38 +++++---- .../Provider/FilterSetProvider.php | 3 +- .../config/services/search_engine.xml | 1 + src/Search/Criteria/Filtering.php | 2 +- src/Search/Criteria/Ordering.php | 2 +- src/Search/Criteria/Paginating.php | 6 +- src/Search/Elastic/ElasticSearchEngine.php | 13 ++- .../Query/ProductInChannelQueryFactory.php | 2 +- .../Query/ProductInMainTaxonQueryFactory.php | 2 +- .../Factory/Sort/SortByFieldQueryFactory.php | 2 +- .../Context/Domain/Shop/ProductContext.php | 80 +++++-------------- .../Context/Hook/ElasticSearchContext.php | 30 +++++++ tests/Behat/Context/Setup/ProductContext.php | 73 ++++++++++++++++- .../Resources/services/searching_products.xml | 6 ++ .../domain/product/searching_products.yml | 7 +- 34 files changed, 237 insertions(+), 198 deletions(-) delete mode 100644 features/shop/product/searching/filtering_list_of_products_by_options.feature create mode 100644 tests/Behat/Context/Hook/ElasticSearchContext.php diff --git a/.travis.yml b/.travis.yml index 385703c..e0911d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,12 +4,16 @@ php: - 7.1 - 5.6 +jdk: + - oraclejdk8 + addons: apt: sources: - elasticsearch-5.x packages: - elasticsearch + - oracle-java8-installer services: - elasticsearch @@ -28,7 +32,7 @@ before_install: install: - composer update --prefer-dist - tests/Application/bin/console doctrine:schema:create --env=test -vvv --no-interaction - - tests/Application/bin/console fos:elastica:reset --env=test -vvv --no-interaction + - tests/Application/bin/console ongr:es:index:create -vvv --no-interaction script: - bin/phpspec run --no-interaction diff --git a/composer.json b/composer.json index 2d0d11f..9cede4c 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ "matthiasnoback/symfony-dependency-injection-test": "^1.1", "php-http/guzzle6-adapter": "^1.1", "phpspec/phpspec": "^3.2", - "phpunit/phpunit": "^5.6" + "phpunit/phpunit": "^5.6", + "behat/mink-selenium2-driver": "^1.3" }, "config": { "bin-dir": "bin" diff --git a/features/shop/product/searching/filtering_list_of_products_by_channel.feature b/features/shop/product/searching/filtering_list_of_products_by_channel.feature index 517e142..48b20de 100644 --- a/features/shop/product/searching/filtering_list_of_products_by_channel.feature +++ b/features/shop/product/searching/filtering_list_of_products_by_channel.feature @@ -5,15 +5,12 @@ Feature: Filtering list of products by channels I want to be able to filter the products Background: - Given the store operates on a channel named "Europe" - And the store also operates on another channel named "Mobile" - And the store also operates on another channel named "Tablets" - And the store has a product "Banana T-Shirt" priced at "$100" in "Tablets" channel - And the store also has a product "Star Wars T-Shirt" priced at "$150" in "Mobile" channel - And the store also has a product "LOTR T-Shirt" priced at "$300" in "Mobile" channel - And the store also has a product "Breaking Bad T-Shirt" priced at "$50" in "Mobile" channel - And the store also has a product "Westworld T-Shirt" priced at "$1000" in "Europe" channel - And the store also has a product "Orange T-Shirt" priced at "$1000" in "Europe" channel + Given the store has a product "Banana T-Shirt" priced at "$100" in "tablets" channel + And the store also has a product "Star Wars T-Shirt" priced at "$150" in "mobile" channel + And the store also has a product "LOTR T-Shirt" priced at "$300" in "mobile" channel + And the store also has a product "Breaking Bad T-Shirt" priced at "$50" in "mobile" channel + And the store also has a product "Westworld T-Shirt" priced at "$1000" in "europe" channel + And the store also has a product "Orange T-Shirt" priced at "$1000" in "europe" channel @domain Scenario: Filtering products by mobile channel diff --git a/features/shop/product/searching/filtering_list_of_products_by_options.feature b/features/shop/product/searching/filtering_list_of_products_by_options.feature deleted file mode 100644 index 9ec826e..0000000 --- a/features/shop/product/searching/filtering_list_of_products_by_options.feature +++ /dev/null @@ -1,29 +0,0 @@ -@searching_products -Feature: Filtering list of products by options - In order to see more specific list of the products - As an Visitor - I want to be able to filter the products - - Background: - Given the store operates on a single channel in "United States" - And the store has 10 Mugs, 20 Stickers and 25 Books - - @domain - Scenario: Filtering products by their type - When I filter them by double mug type - Then I should see 10 products on the list - - @domain - Scenario: Filtering product by their type or size - When I filter them by double mug type or sticker size 7 - Then I should see 30 products on the list - - @domain - Scenario: Filtering product by their size - When I filter them by stickier size 7 - Then I should see 20 products on the list - - @domain - Scenario: List of all products without filtering - When I view the list of the products without filtering - Then I should see 55 products on the list diff --git a/features/shop/product/searching/filtering_list_of_products_by_price_range.feature b/features/shop/product/searching/filtering_list_of_products_by_price_range.feature index c69f4f1..2fdf913 100644 --- a/features/shop/product/searching/filtering_list_of_products_by_price_range.feature +++ b/features/shop/product/searching/filtering_list_of_products_by_price_range.feature @@ -5,8 +5,7 @@ Feature: Filtering list of products by price range I want to be able to filter the products Background: - Given the store operates on a single channel in "United States" - And the store has a product "Banana T-Shirt" priced at "$100" + Given the store has a product "Banana T-Shirt" priced at "$100" And the store also has a product "Star Wars T-Shirt" priced at "$150" And the store also has a product "LOTR T-Shirt" priced at "$300" And the store also has a product "Breaking Bad T-Shirt" priced at "$50" diff --git a/features/shop/product/searching/filtering_list_of_products_by_price_range_and_channel.feature b/features/shop/product/searching/filtering_list_of_products_by_price_range_and_channel.feature index f3c89e0..acc18e1 100644 --- a/features/shop/product/searching/filtering_list_of_products_by_price_range_and_channel.feature +++ b/features/shop/product/searching/filtering_list_of_products_by_price_range_and_channel.feature @@ -5,15 +5,12 @@ Feature: Filtering list of products by channels and price I want to be able to filter the products Background: - Given the store operates on a channel named "Europe" - And the store also operates on another channel named "Mobile" - And the store also operates on another channel named "Tablets" - And the store has a product "Banana T-Shirt" priced at "$100" in "Tablets" channel - And the store also has a product "Star Wars T-Shirt" priced at "$150" in "Mobile" channel - And the store also has a product "LOTR T-Shirt" priced at "$300" in "Mobile" channel - And the store also has a product "Breaking Bad T-Shirt" priced at "$50" in "Mobile" channel - And the store also has a product "Westworld T-Shirt" priced at "$1000" in "Europe" channel - And the store also has a product "Orange T-Shirt" priced at "$1000" in "Europe" channel + Given the store has a product "Banana T-Shirt" priced at "$100" in "tablets" channel + And the store also has a product "Star Wars T-Shirt" priced at "$150" in "mobile" channel + And the store also has a product "LOTR T-Shirt" priced at "$300" in "mobile" channel + And the store also has a product "Breaking Bad T-Shirt" priced at "$50" in "mobile" channel + And the store also has a product "Westworld T-Shirt" priced at "$1000" in "europe" channel + And the store also has a product "Orange T-Shirt" priced at "$1000" in "europe" channel @domain Scenario: Filtering products by mobile channel and price range diff --git a/features/shop/product/searching/filtering_list_of_products_by_taxon.feature b/features/shop/product/searching/filtering_list_of_products_by_taxon.feature index 887d36d..cf1defb 100644 --- a/features/shop/product/searching/filtering_list_of_products_by_taxon.feature +++ b/features/shop/product/searching/filtering_list_of_products_by_taxon.feature @@ -5,22 +5,21 @@ Feature: Filtering list of products by taxon I want to be able to filter the products Background: - Given the store classifies its products as Mugs, Stickers and Books - And the store has 40 Mugs, 15 Stickers and 50 Books + Given the store has 40 Mugs, 15 Stickers and 50 Books @domain Scenario: Filtering products by book - When I filter them by "Books" taxon + When I filter them by "books" taxon Then I should see 50 products on the list @domain Scenario: Filtering product by stickers - When I filter them by "Stickers" taxon + When I filter them by "stickers" taxon Then I should see 15 products on the list @domain Scenario: Filtering product by mugs - When I filter them by "Mugs" taxon + When I filter them by "mugs" taxon Then I should see 40 products on the list @domain diff --git a/features/shop/product/searching/searching_products_by_name.feature b/features/shop/product/searching/searching_products_by_name.feature index de700d6..92da2b7 100644 --- a/features/shop/product/searching/searching_products_by_name.feature +++ b/features/shop/product/searching/searching_products_by_name.feature @@ -5,8 +5,7 @@ Feature: Searching products by name I want to be able to filter the products Background: - Given the store operates on a channel named "Europe" - And the store has a product "Banana T-Shirt" + Given the store has a product "Banana T-Shirt" And the store has a product "Star Wars T-Shirt" And the store has a product "Star Wars Rogue T-Shirt" And the store has a product "Breaking Bad Saul T-Shirt" diff --git a/features/shop/product/sorting/sorting_list_of_products_by_name.feature b/features/shop/product/sorting/sorting_list_of_products_by_name.feature index c1bf0a8..124bb81 100644 --- a/features/shop/product/sorting/sorting_list_of_products_by_name.feature +++ b/features/shop/product/sorting/sorting_list_of_products_by_name.feature @@ -5,15 +5,12 @@ Feature: Sorting list of products by name I want to be able to sort the products Background: - Given the store operates on a channel named "Europe" - And the store also operates on another channel named "Mobile" - And the store also operates on another channel named "Tablets" - And the store has a product "Banana T-Shirt" priced at "$100" in "Tablets" channel - And the store also has a product "Star Wars T-Shirt" priced at "$150" in "Mobile" channel - And the store also has a product "LOTR T-Shirt" priced at "$300" in "Mobile" channel - And the store also has a product "Breaking Bad T-Shirt" priced at "$50" in "Mobile" channel - And the store also has a product "Westworld T-Shirt" priced at "$1000" in "Europe" channel - And the store also has a product "Orange T-Shirt" priced at "$1000" in "Europe" channel + Given the store has a product "Banana T-Shirt" priced at "$100" in "tablets" channel + And the store also has a product "Star Wars T-Shirt" priced at "$150" in "mobile" channel + And the store also has a product "LOTR T-Shirt" priced at "$300" in "mobile" channel + And the store also has a product "Breaking Bad T-Shirt" priced at "$50" in "mobile" channel + And the store also has a product "Westworld T-Shirt" priced at "$1000" in "europe" channel + And the store also has a product "Orange T-Shirt" priced at "$1000" in "europe" channel @domain Scenario: Sorting products by name in ascending order diff --git a/spec/Document/ProductSpec.php b/spec/Document/ProductSpec.php index f78fbb4..31ab9d2 100644 --- a/spec/Document/ProductSpec.php +++ b/spec/Document/ProductSpec.php @@ -2,8 +2,8 @@ namespace spec\Sylius\ElasticSearchPlugin\Document; -use Doctrine\Common\Collections\ArrayCollection; -use Sylius\ElasticSearchPlugin\Document\Attribute; +use ONGR\ElasticsearchBundle\Collection\Collection; +use Sylius\ElasticSearchPlugin\Document\Price; use Sylius\ElasticSearchPlugin\Document\Product; use PhpSpec\ObjectBehavior; @@ -51,9 +51,10 @@ function it_has_description() function it_has_price() { - $this->setPrice(1000); + $price = new Price(); + $this->setPrice($price); - $this->getPrice()->shouldReturn(1000); + $this->getPrice()->shouldReturn($price); } function it_has_taxon_code() @@ -65,7 +66,7 @@ function it_has_taxon_code() function it_has_attributes() { - $attributes = new ArrayCollection([new Attribute()]); + $attributes = new Collection(); $this->setAttributes($attributes); $this->getAttributes()->shouldReturn($attributes); diff --git a/spec/Search/Criteria/FilteringSpec.php b/spec/Search/Criteria/FilteringSpec.php index c0018f4..f407335 100644 --- a/spec/Search/Criteria/FilteringSpec.php +++ b/spec/Search/Criteria/FilteringSpec.php @@ -32,7 +32,7 @@ function it_removes_page_per_page_and_sort_attributes_from_query_parameters() 'size' => 'm', 'sort' => 'name', 'page' => 10, - 'per_page' => 50, + 'limit' => 50, ]]); $this->getFields()->shouldReturn(['option' => 'blue', 'size' => 'm',]); diff --git a/spec/Search/Criteria/OrderingSpec.php b/spec/Search/Criteria/OrderingSpec.php index 455388a..2545a5d 100644 --- a/spec/Search/Criteria/OrderingSpec.php +++ b/spec/Search/Criteria/OrderingSpec.php @@ -21,7 +21,7 @@ function it_can_be_created_from_query_parameters_with_default_direction() 'sort' => 'code', ]]); - $this->getField()->shouldReturn('code'); + $this->getField()->shouldReturn('code.raw'); $this->getDirection()->shouldReturn('asc'); } @@ -31,7 +31,7 @@ function it_can_be_created_from_query_parameters() 'sort' => '-code', ]]); - $this->getField()->shouldReturn('code'); + $this->getField()->shouldReturn('code.raw'); $this->getDirection()->shouldReturn('desc'); } } diff --git a/spec/Search/Criteria/PaginatingSpec.php b/spec/Search/Criteria/PaginatingSpec.php index 5205d92..c3f7d8f 100644 --- a/spec/Search/Criteria/PaginatingSpec.php +++ b/spec/Search/Criteria/PaginatingSpec.php @@ -28,7 +28,7 @@ function it_can_be_created_from_query_parameters_with_default_values_if_paramete { $this->beConstructedThrough('fromQueryParameters', [[ 'page' => -1, - 'per_page' => -100, + 'limit' => -100, ]]); $this->getCurrentPage()->shouldReturn(1); @@ -40,7 +40,7 @@ function it_can_be_created_from_query_parameters() { $this->beConstructedThrough('fromQueryParameters', [[ 'page' => 2, - 'per_page' => 50, + 'limit' => 50, ]]); $this->getCurrentPage()->shouldReturn(2); diff --git a/spec/Search/Elastic/Factory/Query/ProductInChannelQueryFactorySpec.php b/spec/Search/Elastic/Factory/Query/ProductInChannelQueryFactorySpec.php index a11d233..20fea83 100644 --- a/spec/Search/Elastic/Factory/Query/ProductInChannelQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Query/ProductInChannelQueryFactorySpec.php @@ -25,7 +25,7 @@ function it_is_query_factory() function it_creates_product_in_channel_query() { - $this->create(['channel_code' => 'web'])->shouldBeLike(new TermQuery('channelCode', 'web')); + $this->create(['channel_code' => 'web'])->shouldBeLike(new TermQuery('channel_code', 'web')); } function it_cannot_be_created_without_channel_code() diff --git a/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php b/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php index 1ad1a9f..4284b5e 100644 --- a/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php @@ -25,7 +25,7 @@ function it_is_query_factory() function it_creates_query() { - $this->create(['taxon_code' => 'mugs'])->shouldBeLike(new TermQuery('taxonCode', 'mugs')); + $this->create(['taxon_code' => 'mugs'])->shouldBeLike(new TermQuery('taxon_code', 'mugs')); } function it_cannot_create_query_if_there_is_no_required_parameters() diff --git a/spec/Search/Elastic/Factory/Sort/SortByFieldQueryFactorySpec.php b/spec/Search/Elastic/Factory/Sort/SortByFieldQueryFactorySpec.php index c409667..0836fa4 100644 --- a/spec/Search/Elastic/Factory/Sort/SortByFieldQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Sort/SortByFieldQueryFactorySpec.php @@ -27,20 +27,20 @@ function it_creates_descending_field_sort_query() { $ordering = Ordering::fromQueryParameters(['sort' => '-price']); - $this->create($ordering)->shouldBeLike(new FieldSort('raw_price', 'desc')); + $this->create($ordering)->shouldBeLike(new FieldSort('price.raw', 'desc')); } function it_creates_ascending_field_sort_query() { $ordering = Ordering::fromQueryParameters(['sort' => 'price']); - $this->create($ordering)->shouldBeLike(new FieldSort('raw_price', 'asc')); + $this->create($ordering)->shouldBeLike(new FieldSort('price.raw', 'asc')); } function it_creates_ascending_by_name_field_sort_query_by_default() { $ordering = Ordering::fromQueryParameters([]); - $this->create($ordering)->shouldBeLike(new FieldSort('raw_name', 'asc')); + $this->create($ordering)->shouldBeLike(new FieldSort('name.raw', 'asc')); } } diff --git a/src/DependencyInjection/SyliusElasticSearchExtension.php b/src/DependencyInjection/SyliusElasticSearchExtension.php index debba22..c3419ea 100644 --- a/src/DependencyInjection/SyliusElasticSearchExtension.php +++ b/src/DependencyInjection/SyliusElasticSearchExtension.php @@ -18,15 +18,6 @@ public function load(array $configs, ContainerBuilder $container) $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.xml'); - $this->createFilterSetsParameter($config['filter_sets'], $container); - } - - /** - * @param array $config - * @param ContainerBuilder $container - */ - private function createFilterSetsParameter(array $config, ContainerBuilder $container) - { - $container->setParameter('sylius_elastic_search.filter_sets', $config); + $container->setParameter('sylius_elastic_search.filter_sets', $config['filter_sets']); } } diff --git a/src/Document/Attribute.php b/src/Document/Attribute.php index 13a324a..181af6b 100644 --- a/src/Document/Attribute.php +++ b/src/Document/Attribute.php @@ -19,14 +19,14 @@ final class Attribute /** * @var string * - * @ElasticSearch\Property(type="text", options={"analyzer":"incrementalAnalyzer"}) + * @ElasticSearch\Property(type="text") */ private $name; /** * @var string * - * @ElasticSearch\Property(type="text", options={"analyzer":"incrementalAnalyzer"}) + * @ElasticSearch\Property(type="text") */ private $value; diff --git a/src/Document/Price.php b/src/Document/Price.php index da1763d..d1aa991 100644 --- a/src/Document/Price.php +++ b/src/Document/Price.php @@ -24,34 +24,34 @@ final class Price private $currency; /** - * @param int $amount + * @return int */ - public function setAmount($amount) + public function getAmount() { - $this->amount = $amount; + return $this->amount; } /** - * @param string $currency + * @param int $amount */ - public function setCurrency($currency) + public function setAmount($amount) { - $this->currency = $currency; + $this->amount = $amount; } /** - * @return int + * @return string */ - public function getAmount() + public function getCurrency() { - return $this->amount; + return $this->currency; } /** - * @return string + * @param string $currency */ - public function getCurrency() + public function setCurrency($currency) { - return $this->currency; + $this->currency = $currency; } } diff --git a/src/Document/Product.php b/src/Document/Product.php index 4b28795..04a7c30 100644 --- a/src/Document/Product.php +++ b/src/Document/Product.php @@ -2,8 +2,8 @@ namespace Sylius\ElasticSearchPlugin\Document; -use Doctrine\Common\Collections\ArrayCollection; use ONGR\ElasticsearchBundle\Annotation as ElasticSearch; +use ONGR\ElasticsearchBundle\Collection\Collection; /** * @ElasticSearch\Document(type="product") @@ -20,7 +20,17 @@ final class Product /** * @var string * - * @ElasticSearch\Property(type="text", options={"analyzer":"incrementalAnalyzer"}) + * @ElasticSearch\Property( + * type="text", + * name="name", + * options={ + * "analyzer"="standard", + * "fields"={ + * "raw"={"type"="keyword"}, + * "standard"={"type"="text", "analyzer"="standard"} + * } + * } + * ) */ private $name; @@ -41,14 +51,14 @@ final class Product /** * @var string * - * @ElasticSearch\Property(type="text", options={"analyzer":"incrementalAnalyzer"}) + * @ElasticSearch\Property(type="text") */ private $description; /** - * @var int + * @var Price * - * @ElasticSearch\Embedded(class="ElasticSearchPlugin:Price") + * @ElasticSearch\Embedded(class="SyliusElasticSearchPlugin:Price") */ private $price; @@ -60,9 +70,9 @@ final class Product private $taxonCode; /** - * @var ArrayCollection + * @var Collection * - * @ElasticSearch\Embedded(class="ElasticSearchPlugin:Attribute", multiple=true) + * @ElasticSearch\Embedded(class="SyliusElasticSearchPlugin:Attribute", multiple=true) */ private $attributes; @@ -75,7 +85,7 @@ final class Product public function __construct() { - $this->attributes = new ArrayCollection(); + $this->attributes = new Collection(); } /** @@ -159,7 +169,7 @@ public function setDescription($description) } /** - * @return int + * @return Price */ public function getPrice() { @@ -167,9 +177,9 @@ public function getPrice() } /** - * @param int $price + * @param Price $price */ - public function setPrice($price) + public function setPrice(Price $price) { $this->price = $price; } @@ -191,7 +201,7 @@ public function setTaxonCode($taxonCode) } /** - * @return ArrayCollection + * @return Collection */ public function getAttributes() { @@ -199,9 +209,9 @@ public function getAttributes() } /** - * @param ArrayCollection $attributes + * @param Collection $attributes */ - public function setAttributes(ArrayCollection $attributes) + public function setAttributes(Collection $attributes) { $this->attributes = $attributes; } diff --git a/src/Form/Configuration/Provider/FilterSetProvider.php b/src/Form/Configuration/Provider/FilterSetProvider.php index d00aa27..44f018f 100644 --- a/src/Form/Configuration/Provider/FilterSetProvider.php +++ b/src/Form/Configuration/Provider/FilterSetProvider.php @@ -11,7 +11,7 @@ final class FilterSetProvider implements FilterSetProviderInterface { /** - * @var FilterSetProviderInterface[] + * @var PriorityQueue */ private $filterSetProviders; @@ -34,6 +34,7 @@ public function addFilterSetProvider(FilterSetProviderInterface $filterSetProvid */ public function getFilterSetConfiguration($filterSetName) { + /** @var FilterSetProviderInterface $filterSetProvider */ foreach ($this->filterSetProviders as $filterSetProvider) { try { return $filterSetProvider->getFilterSetConfiguration($filterSetName); diff --git a/src/Resources/config/services/search_engine.xml b/src/Resources/config/services/search_engine.xml index 87cea50..b5ea5c5 100644 --- a/src/Resources/config/services/search_engine.xml +++ b/src/Resources/config/services/search_engine.xml @@ -7,6 +7,7 @@ + diff --git a/src/Search/Criteria/Filtering.php b/src/Search/Criteria/Filtering.php index f2480d9..26152df 100644 --- a/src/Search/Criteria/Filtering.php +++ b/src/Search/Criteria/Filtering.php @@ -30,7 +30,7 @@ public static function fromQueryParameters(array $queryParameters) $fields = $queryParameters; unset($fields['page']); - unset($fields['per_page']); + unset($fields['limit']); unset($fields['sort']); return new self($fields); diff --git a/src/Search/Criteria/Ordering.php b/src/Search/Criteria/Ordering.php index 3a913a2..5d01ccd 100644 --- a/src/Search/Criteria/Ordering.php +++ b/src/Search/Criteria/Ordering.php @@ -28,7 +28,7 @@ final class Ordering */ private function __construct($field, $direction) { - $this->field = $field; + $this->field = $field.'.raw'; $this->direction = $direction; } diff --git a/src/Search/Criteria/Paginating.php b/src/Search/Criteria/Paginating.php index b5b66db..7ed0687 100644 --- a/src/Search/Criteria/Paginating.php +++ b/src/Search/Criteria/Paginating.php @@ -8,7 +8,7 @@ final class Paginating { const DEFAULT_CURRENT_PAGE = 1; - const DEFAULT_ITEMS_PER_PAGE = 10; + const DEFAULT_ITEMS_LIMIT = 10; /** * @var int @@ -38,7 +38,7 @@ private function __construct($currentPage, $itemsPerPage) $this->itemsPerPage = (int) $itemsPerPage; if (0 >= $itemsPerPage) { - $this->itemsPerPage = self::DEFAULT_ITEMS_PER_PAGE; + $this->itemsPerPage = self::DEFAULT_ITEMS_LIMIT; } $this->offset = $this->currentPage * $this->itemsPerPage - $this->itemsPerPage; @@ -52,7 +52,7 @@ private function __construct($currentPage, $itemsPerPage) public static function fromQueryParameters(array $parameters) { $currentPage = isset($parameters['page']) ? $parameters['page'] : self::DEFAULT_CURRENT_PAGE; - $itemsPerPage = isset($parameters['per_page']) ? $parameters['per_page'] : self::DEFAULT_ITEMS_PER_PAGE; + $itemsPerPage = isset($parameters['limit']) ? $parameters['limit'] : self::DEFAULT_ITEMS_LIMIT; return new self($currentPage, $itemsPerPage); } diff --git a/src/Search/Elastic/ElasticSearchEngine.php b/src/Search/Elastic/ElasticSearchEngine.php index 1a90def..cc00cc0 100644 --- a/src/Search/Elastic/ElasticSearchEngine.php +++ b/src/Search/Elastic/ElasticSearchEngine.php @@ -22,12 +22,19 @@ final class ElasticSearchEngine implements SearchEngineInterface */ private $searchCriteriaApplicators = []; + /** + * @var SearchCriteriaApplicatorInterface + */ + private $sortingApplicator; + /** * @param Manager $manager + * @param SearchCriteriaApplicatorInterface $sortingApplicator */ - public function __construct(Manager $manager) + public function __construct(Manager $manager, SearchCriteriaApplicatorInterface $sortingApplicator) { $this->manager = $manager; + $this->sortingApplicator = $sortingApplicator; } /** @@ -50,7 +57,7 @@ public function match(Criteria $criteria) $search = $repository->createSearch(); - foreach ($this->searchCriteriaApplicators as $filter => $searchCriteriaApplicator) { + foreach ($criteria->getFiltering()->getFields() as $filter) { if (!is_object($filter)) { continue; } @@ -60,6 +67,8 @@ public function match(Criteria $criteria) } } + $this->sortingApplicator->applyOrdering($criteria->getOrdering(), $search); + return $repository->findDocuments($search); } } diff --git a/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php index fe01b9d..2cee10b 100644 --- a/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInChannelQueryFactory.php @@ -20,6 +20,6 @@ public function create(array $parameters = []) throw new MissingQueryParameterException('channel_code', get_class($this)); } - return new TermQuery('channelCode', strtolower($parameters['channel_code'])); + return new TermQuery('channel_code', strtolower($parameters['channel_code'])); } } diff --git a/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php index f4afbbf..f029e9c 100644 --- a/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php @@ -19,6 +19,6 @@ public function create(array $parameters = []) throw new MissingQueryParameterException('taxon_code', get_class($this)); } - return new TermQuery('taxonCode', strtolower($parameters['taxon_code'])); + return new TermQuery('taxon_code', strtolower($parameters['taxon_code'])); } } diff --git a/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php b/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php index fcb7598..f2531d8 100644 --- a/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php +++ b/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php @@ -15,6 +15,6 @@ final class SortByFieldQueryFactory implements SortFactoryInterface */ public function create(Ordering $ordering) { - return new FieldSort('raw_' . $ordering->getField(), $ordering->getDirection()); + return new FieldSort($ordering->getField(), $ordering->getDirection()); } } diff --git a/tests/Behat/Context/Domain/Shop/ProductContext.php b/tests/Behat/Context/Domain/Shop/ProductContext.php index 12ccac3..836872c 100644 --- a/tests/Behat/Context/Domain/Shop/ProductContext.php +++ b/tests/Behat/Context/Domain/Shop/ProductContext.php @@ -12,8 +12,8 @@ namespace Tests\Sylius\ElasticSearchPlugin\Behat\Context\Domain\Shop; use Behat\Behat\Context\Context; -use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface; -use FOS\ElasticaBundle\Paginator\PartialResultsInterface; +use ONGR\ElasticsearchBundle\Result\DocumentIterator; +use Sylius\ElasticSearchPlugin\Document\Product; use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductHasOptionCodesFilter; use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInChannelFilter; @@ -22,15 +22,8 @@ use Sylius\ElasticSearchPlugin\Search\Criteria\SearchPhrase; use Sylius\ElasticSearchPlugin\Search\SearchEngineInterface; use Sylius\Behat\Service\SharedStorageInterface; -use Sylius\Component\Core\Model\ChannelInterface; -use Sylius\Component\Core\Model\Product; -use Sylius\Component\Core\Model\ProductInterface; -use Sylius\Component\Core\Model\TaxonInterface; use Webmozart\Assert\Assert; -/** - * @author Arkadiusz Krakowiak - */ final class ProductContext implements Context { /** @@ -95,7 +88,6 @@ public function iFilterThemByStickierSize($stickerSizeValue) */ public function iFilterThemByPriceBetweenAnd($graterThan, $lessThan) { - sleep(3); $criteria = Criteria::fromQueryParameters(Product::class, [new ProductInPriceRangeFilter($graterThan, $lessThan)]); $this->match($criteria); } @@ -110,23 +102,21 @@ public function iViewTheListOfTheProductsWithoutFiltering() } /** - * @When /^I filter them by (channel "[^"]+")$/ + * @When I filter them by channel :channelCode */ - public function iFilterThemByChannel(ChannelInterface $channel) + public function iFilterThemByChannel($channelCode) { - sleep(3); - $criteria = Criteria::fromQueryParameters(Product::class, [new ProductInChannelFilter($channel->getCode())]); + $criteria = Criteria::fromQueryParameters(Product::class, [new ProductInChannelFilter($channelCode)]); $this->match($criteria); } /** - * @When /^I filter them by (channel "[^"]+") and price between ("[^"]+") and ("[^"]+")$/ + * @When /^I filter them by channel "([^"]+)" and price between ("[^"]+") and ("[^"]+")$/ */ - public function iFilterThemByChannelAndPriceBetweenAnd(ChannelInterface $channel, $graterThan, $lessThan) + public function iFilterThemByChannelAndPriceBetweenAnd($channelCode, $graterThan, $lessThan) { - sleep(3); $criteria = Criteria::fromQueryParameters(Product::class, [ - new ProductInChannelFilter($channel->getCode()), + new ProductInChannelFilter($channelCode), new ProductInPriceRangeFilter($graterThan, $lessThan), ]); @@ -134,11 +124,11 @@ public function iFilterThemByChannelAndPriceBetweenAnd(ChannelInterface $channel } /** - * @When I filter them by :taxon taxon + * @When I filter them by :taxonCode taxon */ - public function iFilterThemByTaxon(TaxonInterface $taxon) + public function iFilterThemByTaxon($taxonCode) { - $criteria = Criteria::fromQueryParameters(Product::class, [new ProductInTaxonFilter($taxon->getCode())]); + $criteria = Criteria::fromQueryParameters(Product::class, [new ProductInTaxonFilter($taxonCode)]); $this->match($criteria); } @@ -147,7 +137,6 @@ public function iFilterThemByTaxon(TaxonInterface $taxon) */ public function iSortThemByNameInAscendingOrder($field, $order) { - sleep(3); if ('descending' === $order) { $field = '-' . $field; } @@ -161,8 +150,6 @@ public function iSortThemByNameInAscendingOrder($field, $order) */ public function iSearchForProductsWithName($name) { - sleep(3); - $criteria = Criteria::fromQueryParameters(Product::class, [new SearchPhrase($name)]); $this->match($criteria); } @@ -172,11 +159,10 @@ public function iSearchForProductsWithName($name) */ public function iShouldSeeProductsOnTheList($numberOfProducts) { - /** @var PaginatorAdapterInterface $result */ + /** @var DocumentIterator $result */ $result = $this->sharedStorage->get('search_result'); - var_dump($result->getResults(1, 10)->toArray()); -// Assert::eq($result->getTotalHits, $numberOfProducts); + Assert::eq($result->count(), $numberOfProducts); } /** @@ -184,24 +170,21 @@ public function iShouldSeeProductsOnTheList($numberOfProducts) */ public function iShouldSeeProductsInOrderLike(...$productNames) { - /** @var PaginatorAdapterInterface $result */ + /** @var DocumentIterator $searchResult */ $searchResult = $this->sharedStorage->get('search_result'); - /** @var PartialResultsInterface $partialResult */ - $partialResult = $searchResult->getResults(0, 100); - /** * @var int $position - * @var ProductInterface $result + * @var Product $product */ - foreach ($partialResult->toArray() as $position => $result) { - if ($result->getName() !== $productNames[$position]) { + foreach ($searchResult as $position => $product) { + if ($product->getName() !== $productNames[$position]) { throw new \RuntimeException( sprintf( 'Sorting failed at position "%s" expected value was "%s", but got "%s"', $position + 1, $productNames[$position], - $result + $product->getName() ) ); } @@ -216,31 +199,12 @@ public function iShouldSeeProductsInOrderLike(...$productNames) */ public function itShouldBe(...$expectedProductNames) { - /** @var PaginatorAdapterInterface $result */ + /** @var DocumentIterator $searchResult */ $searchResult = $this->sharedStorage->get('search_result'); - /** @var PartialResultsInterface $partialResult */ - $partialResult = $searchResult->getResults(0, 100); - - $resultProductNames = array_map(function (ProductInterface $product) { - return $product->getName(); - }, $partialResult->toArray()); - - $expectedProductCount = count($expectedProductNames); - $resultProductCount = count($resultProductNames); - - Assert::same($expectedProductCount, $resultProductCount); - - foreach ($expectedProductNames as $expectedProductName) { - Assert::oneOf( - $expectedProductName, - $resultProductNames, - sprintf( - 'Expected product with name "%s", does not exist in search result. Got "%s"', - $expectedProductName, - implode(',', $resultProductNames) - ) - ); + /** @var Product $product */ + foreach ($searchResult as $product) { + Assert::oneOf($product->getName(), $expectedProductNames); } } diff --git a/tests/Behat/Context/Hook/ElasticSearchContext.php b/tests/Behat/Context/Hook/ElasticSearchContext.php new file mode 100644 index 0000000..b426e32 --- /dev/null +++ b/tests/Behat/Context/Hook/ElasticSearchContext.php @@ -0,0 +1,30 @@ +manager = $manager; + } + + /** + * @BeforeScenario + */ + public function purge() + { + $this->manager->dropAndCreateIndex(); + } +} diff --git a/tests/Behat/Context/Setup/ProductContext.php b/tests/Behat/Context/Setup/ProductContext.php index d0ab8ab..c62c6f1 100644 --- a/tests/Behat/Context/Setup/ProductContext.php +++ b/tests/Behat/Context/Setup/ProductContext.php @@ -12,17 +12,84 @@ namespace Tests\Sylius\ElasticSearchPlugin\Behat\Context\Setup; use Behat\Behat\Context\Context; +use Doctrine\ORM\Id\UuidGenerator; +use ONGR\ElasticsearchBundle\Service\Manager; +use Sylius\ElasticSearchPlugin\Document\Price; +use Sylius\ElasticSearchPlugin\Document\Product; -/** - * @author Arkadiusz Krakowiak - */ final class ProductContext implements Context { + /** + * @var Manager + */ + private $manager; + + /** + * @param Manager $manager + */ + public function __construct(Manager $manager) + { + $this->manager = $manager; + } + /** * @Given the store has :mugsNumber Mugs, :stickersNumber Stickers and :booksNumber Books */ public function theStoreHasAboutMugsAndStickers($mugsNumber, $stickersNumber, $booksNumber) { + $this->generateProductsInTaxon($mugsNumber, 'mugs'); + $this->generateProductsInTaxon($stickersNumber, 'stickers'); + $this->generateProductsInTaxon($booksNumber, 'books'); + } + + /** + * @Given the store has a product :productName + * @Given the store has a :productName product + * @Given I added a product :productName + * @Given /^the store(?:| also) has a product "([^"]+)" priced at ("[^"]+")$/ + * @Given /^the store(?:| also) has a product "([^"]+)" priced at ("[^"]+") in "([^"]+)" channel$/ + */ + public function storeHasAProductPricedAt($productName, $price = 100, $channelCode = null) + { + $this->manager->persist($this->createProduct($productName, $price, $channelCode)); + $this->manager->commit(); + } + + /** + * @param int $howMany + * @param string $taxonCode + */ + private function generateProductsInTaxon($howMany, $taxonCode) + { + for ($i = 0; $i < $howMany; $i++) { + $product = new Product(); + $product->setTaxonCode($taxonCode); + $product->setCode(uniqid()); + $this->manager->persist($product); + } + + $this->manager->commit(); + } + + /** + * @param string $productName + * @param int $priceAmount + * @param string $channelCode + * + * @return Product + */ + private function createProduct($productName, $priceAmount, $channelCode) + { + $price = new Price(); + $price->setCurrency('USD'); + $price->setAmount($priceAmount); + + $product = new Product(); + $product->setCode(uniqid()); + $product->setPrice($price); + $product->setChannelCode($channelCode); + $product->setName($productName); + return $product; } } diff --git a/tests/Behat/Resources/services/searching_products.xml b/tests/Behat/Resources/services/searching_products.xml index 57a04f2..51636f7 100644 --- a/tests/Behat/Resources/services/searching_products.xml +++ b/tests/Behat/Resources/services/searching_products.xml @@ -6,6 +6,7 @@ + @@ -14,5 +15,10 @@ + + + + + diff --git a/tests/Behat/Resources/suites/shop/domain/product/searching_products.yml b/tests/Behat/Resources/suites/shop/domain/product/searching_products.yml index abcc117..fa85c0b 100644 --- a/tests/Behat/Resources/suites/shop/domain/product/searching_products.yml +++ b/tests/Behat/Resources/suites/shop/domain/product/searching_products.yml @@ -2,16 +2,11 @@ default: suites: domain_shop_searching_product: contexts_services: - - sylius.behat.context.hook.doctrine_orm + - sylius_elastic_search.behat.context.hook.elastic_search - - sylius.behat.context.transform.channel - sylius.behat.context.transform.lexical - - sylius.behat.context.transform.taxon - sylius_elastic_search.behat.context.setup.product - - sylius.behat.context.setup.channel - - sylius.behat.context.setup.taxonomy - - sylius.behat.context.setup.product - sylius_elastic_search.behat.context.domain.shop.product filters: From 505822bbe36dffd67d971aff51d055561bbfb821 Mon Sep 17 00:00:00 2001 From: Arminek Date: Mon, 29 May 2017 04:52:44 +0200 Subject: [PATCH 5/6] [ElasticSearch] Add projections --- composer.json | 3 +- spec/Document/AttributeSpec.php | 7 +- spec/Document/AttributeValueSpec.php | 38 +++++ spec/Document/ProductSpec.php | 22 ++- spec/Document/TaxonCodeSpec.php | 22 +++ spec/EventListener/ProductPublisherSpec.php | 42 +++++ spec/Projection/ProductProjectorSpec.php | 78 +++++++++ .../ProductInMainTaxonQueryFactorySpec.php | 2 +- src/Controller/SearchController.php | 13 ++ src/Document/Attribute.php | 23 --- src/Document/AttributeValue.php | 80 +++++++++ src/Document/Product.php | 58 +++++-- src/Document/TaxonCode.php | 34 ++++ src/Event/ProductCreated.php | 39 +++++ src/EventListener/ProductPublisher.php | 35 ++++ src/Factory/ProductFactory.php | 99 +++++++++++ src/Factory/ProductFactoryInterface.php | 29 ++++ src/Projection/ProductProjector.php | 56 +++++++ src/Resources/config/services.xml | 11 ++ .../Query/ProductInMainTaxonQueryFactory.php | 2 +- tests/Application/app/AppKernel.php | 2 + tests/Behat/Context/Setup/ProductContext.php | 22 ++- tests/Event/ProductCreatedTest.php | 21 +++ tests/Factory/ProductFactoryTest.php | 158 ++++++++++++++++++ 24 files changed, 838 insertions(+), 58 deletions(-) create mode 100644 spec/Document/AttributeValueSpec.php create mode 100644 spec/Document/TaxonCodeSpec.php create mode 100644 spec/EventListener/ProductPublisherSpec.php create mode 100644 spec/Projection/ProductProjectorSpec.php create mode 100644 src/Document/AttributeValue.php create mode 100644 src/Document/TaxonCode.php create mode 100644 src/Event/ProductCreated.php create mode 100644 src/EventListener/ProductPublisher.php create mode 100644 src/Factory/ProductFactory.php create mode 100644 src/Factory/ProductFactoryInterface.php create mode 100644 src/Projection/ProductProjector.php create mode 100644 tests/Event/ProductCreatedTest.php create mode 100644 tests/Factory/ProductFactoryTest.php diff --git a/composer.json b/composer.json index 9cede4c..2ea254d 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ "sylius/sylius": "dev-master", "ongr/elasticsearch-dsl": "^5.0", - "ongr/elasticsearch-bundle": "^5.0" + "ongr/elasticsearch-bundle": "^5.0", + "simple-bus/symfony-bridge": "^4.1" }, "require-dev": { "behat/behat": "^3.2", diff --git a/spec/Document/AttributeSpec.php b/spec/Document/AttributeSpec.php index 28a87bc..d98c7b2 100644 --- a/spec/Document/AttributeSpec.php +++ b/spec/Document/AttributeSpec.php @@ -2,6 +2,7 @@ namespace spec\Sylius\ElasticSearchPlugin\Document; +use ONGR\ElasticsearchBundle\Collection\Collection; use Sylius\ElasticSearchPlugin\Document\Attribute; use PhpSpec\ObjectBehavior; @@ -12,11 +13,11 @@ function it_is_initializable() $this->shouldHaveType(Attribute::class); } - function it_has_value() + function it_has_code() { - $this->setValue('red'); + $this->setCode('color'); - $this->getValue()->shouldReturn('red'); + $this->getCode()->shouldReturn('color'); } function it_has_name() diff --git a/spec/Document/AttributeValueSpec.php b/spec/Document/AttributeValueSpec.php new file mode 100644 index 0000000..8ae2ca1 --- /dev/null +++ b/spec/Document/AttributeValueSpec.php @@ -0,0 +1,38 @@ +shouldHaveType(AttributeValue::class); + } + + function it_has_value() + { + $this->setValue('Red'); + + $this->getValue()->shouldReturn('Red'); + } + + function it_has_attribute() + { + $attribute = new Attribute(); + $this->setAttribute($attribute); + + $this->getAttribute()->shouldReturn($attribute); + } + + function it_has_code() + { + $this->setCode('red'); + + $this->getCode()->shouldReturn('red'); + } +} diff --git a/spec/Document/ProductSpec.php b/spec/Document/ProductSpec.php index 31ab9d2..5124b3e 100644 --- a/spec/Document/ProductSpec.php +++ b/spec/Document/ProductSpec.php @@ -6,6 +6,7 @@ use Sylius\ElasticSearchPlugin\Document\Price; use Sylius\ElasticSearchPlugin\Document\Product; use PhpSpec\ObjectBehavior; +use Sylius\ElasticSearchPlugin\Document\TaxonCode; final class ProductSpec extends ObjectBehavior { @@ -57,18 +58,27 @@ function it_has_price() $this->getPrice()->shouldReturn($price); } - function it_has_taxon_code() + function it_has_main_taxon_code() { - $this->setTaxonCode('Tree'); + $taxonCode = new TaxonCode(); + $this->setMainTaxonCode($taxonCode); - $this->getTaxonCode()->shouldReturn('Tree'); + $this->getMainTaxonCode()->shouldReturn($taxonCode); + } + + function it_has_taxon_codes() + { + $taxonCodes = new Collection(); + $this->setTaxonCodes($taxonCodes); + + $this->getTaxonCodes()->shouldReturn($taxonCodes); } function it_has_attributes() { - $attributes = new Collection(); - $this->setAttributes($attributes); + $attributeValues = new Collection(); + $this->setAttributeValues($attributeValues); - $this->getAttributes()->shouldReturn($attributes); + $this->getAttributeValues()->shouldReturn($attributeValues); } } diff --git a/spec/Document/TaxonCodeSpec.php b/spec/Document/TaxonCodeSpec.php new file mode 100644 index 0000000..83d0f65 --- /dev/null +++ b/spec/Document/TaxonCodeSpec.php @@ -0,0 +1,22 @@ +shouldHaveType(TaxonCode::class); + } + + function it_has_value() + { + $this->setValue('mug'); + + $this->getValue()->shouldReturn('mug'); + } +} diff --git a/spec/EventListener/ProductPublisherSpec.php b/spec/EventListener/ProductPublisherSpec.php new file mode 100644 index 0000000..2bf64a8 --- /dev/null +++ b/spec/EventListener/ProductPublisherSpec.php @@ -0,0 +1,42 @@ +beConstructedWith($eventBus); + } + + function it_is_initializable() + { + $this->shouldHaveType(ProductPublisher::class); + } + + function it_publishes_product_event(MessageBus $eventBus, LifecycleEventArgs $event, ProductInterface $product) + { + $event->getEntity()->willReturn($product); + + $eventBus->handle(ProductCreated::occur($product->getWrappedObject()))->shouldBeCalled(); + + $this->postPersist($event); + } + + function it_does_not_publish_product_event_if_entity_is_not_a_product(MessageBus $eventBus, LifecycleEventArgs $event) + { + $event->getEntity()->willReturn(new \stdClass()); + + $eventBus->handle(Argument::any())->shouldNotBeCalled(); + + $this->postPersist($event); + } +} diff --git a/spec/Projection/ProductProjectorSpec.php b/spec/Projection/ProductProjectorSpec.php new file mode 100644 index 0000000..ba2597a --- /dev/null +++ b/spec/Projection/ProductProjectorSpec.php @@ -0,0 +1,78 @@ +beConstructedWith($manager, $factory); + } + + function it_is_initializable() + { + $this->shouldHaveType(ProductProjector::class); + } + + function it_saves_product_document_if_product_has_channel_defined( + Manager $manager, + ProductFactoryInterface $factory, + ProductInterface $product, + LocaleInterface $locale, + ChannelInterface $channel + ) { + $channel->getLocales()->willReturn(new ArrayCollection([$locale->getWrappedObject()])); + $product->getChannels()->willReturn(new ArrayCollection([$channel->getWrappedObject()])); + + $productDocument = new Product(); + $factory->createFromSyliusSimpleProductModel($product, $locale, $channel)->willReturn($productDocument); + + $manager->persist($productDocument)->shouldBeCalled(); + $manager->commit()->shouldBeCalled(); + + $this->handleProductCreated(ProductCreated::occur($product->getWrappedObject())); + } + + function it_does_not_save_product_document_if_product_has_not_channel_defined( + Manager $manager, + ProductFactoryInterface $factory, + ProductInterface $product + ) { + $product->getChannels()->willReturn(new ArrayCollection([])); + $factory->createFromSyliusSimpleProductModel(Argument::any(), Argument::any(), Argument::any())->shouldNotBeCalled(); + + $manager->persist(Argument::any())->shouldNotBeCalled(); + $manager->commit()->shouldBeCalled(); + + $this->handleProductCreated(ProductCreated::occur($product->getWrappedObject())); + } + + function it_does_not_save_product_document_if_channel_has_not_locales_defined( + Manager $manager, + ProductFactoryInterface $factory, + ProductInterface $product, + ChannelInterface $channel + ) { + $channel->getLocales()->willReturn(new ArrayCollection([])); + $product->getChannels()->willReturn(new ArrayCollection([$channel->getWrappedObject()])); + + $factory->createFromSyliusSimpleProductModel(Argument::any(), Argument::any(), Argument::any())->shouldNotBeCalled(); + + $manager->persist(Argument::any())->shouldNotBeCalled(); + $manager->commit()->shouldBeCalled(); + + $this->handleProductCreated(ProductCreated::occur($product->getWrappedObject())); + } +} diff --git a/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php b/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php index 4284b5e..acba83f 100644 --- a/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactorySpec.php @@ -25,7 +25,7 @@ function it_is_query_factory() function it_creates_query() { - $this->create(['taxon_code' => 'mugs'])->shouldBeLike(new TermQuery('taxon_code', 'mugs')); + $this->create(['taxon_code' => 'mugs'])->shouldBeLike(new TermQuery('main_taxon_code.value', 'mugs')); } function it_cannot_create_query_if_there_is_no_required_parameters() diff --git a/src/Controller/SearchController.php b/src/Controller/SearchController.php index 40e09e1..32b8e91 100644 --- a/src/Controller/SearchController.php +++ b/src/Controller/SearchController.php @@ -12,8 +12,12 @@ namespace Sylius\ElasticSearchPlugin\Controller; use FOS\RestBundle\View\ConfigurableViewHandlerInterface; +use FOS\RestBundle\View\View; +use Sylius\ElasticSearchPlugin\Document\Product; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\SearchEngineInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; /** * @author Arkadiusz Krakowiak @@ -42,9 +46,18 @@ public function __construct(ConfigurableViewHandlerInterface $restViewHandler, S /** * @param Request $request + * + * @return Response */ public function searchAction(Request $request) { + $content = $request->getContent(); + $criteria = Criteria::fromQueryParameters(Product::class, json_decode($content, true)); + $result = $this->searchEngine->match($criteria); + + $view = View::create($result); + + return $this->restViewHandler->handle($view); } } diff --git a/src/Document/Attribute.php b/src/Document/Attribute.php index 181af6b..c3bc094 100644 --- a/src/Document/Attribute.php +++ b/src/Document/Attribute.php @@ -23,13 +23,6 @@ final class Attribute */ private $name; - /** - * @var string - * - * @ElasticSearch\Property(type="text") - */ - private $value; - /** * @return string */ @@ -61,20 +54,4 @@ public function setName($name) { $this->name = $name; } - - /** - * @return string - */ - public function getValue() - { - return $this->value; - } - - /** - * @param string $value - */ - public function setValue($value) - { - $this->value = $value; - } } diff --git a/src/Document/AttributeValue.php b/src/Document/AttributeValue.php new file mode 100644 index 0000000..75c4dc1 --- /dev/null +++ b/src/Document/AttributeValue.php @@ -0,0 +1,80 @@ +code; + } + + /** + * @param string $code + */ + public function setCode($code) + { + $this->code = $code; + } + + /** + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * @param string $value + */ + public function setValue($value) + { + $this->value = $value; + } + + /** + * @return Attribute + */ + public function getAttribute() + { + return $this->attribute; + } + + /** + * @param Attribute $attribute + */ + public function setAttribute(Attribute $attribute) + { + $this->attribute = $attribute; + } +} diff --git a/src/Document/Product.php b/src/Document/Product.php index 04a7c30..eb435b3 100644 --- a/src/Document/Product.php +++ b/src/Document/Product.php @@ -63,18 +63,25 @@ final class Product private $price; /** - * @var string + * @var TaxonCode * - * @ElasticSearch\Property(type="keyword") + * @ElasticSearch\Embedded(class="SyliusElasticSearchPlugin:TaxonCode") + */ + private $mainTaxonCode; + + /** + * @var Collection + * + * @ElasticSearch\Embedded(class="SyliusElasticSearchPlugin:TaxonCode", multiple=true) */ - private $taxonCode; + private $taxonCodes; /** * @var Collection * - * @ElasticSearch\Embedded(class="SyliusElasticSearchPlugin:Attribute", multiple=true) + * @ElasticSearch\Embedded(class="SyliusElasticSearchPlugin:AttributeValue", multiple=true) */ - private $attributes; + private $attributeValues; /** * @var \DateTime @@ -85,7 +92,8 @@ final class Product public function __construct() { - $this->attributes = new Collection(); + $this->attributeValues = new Collection(); + $this->taxonCodes = new Collection(); } /** @@ -185,35 +193,51 @@ public function setPrice(Price $price) } /** - * @return string + * @return TaxonCode + */ + public function getMainTaxonCode() + { + return $this->mainTaxonCode; + } + + /** + * @param TaxonCode $mainTaxonCode + */ + public function setMainTaxonCode(TaxonCode $mainTaxonCode) + { + $this->mainTaxonCode = $mainTaxonCode; + } + + /** + * @return Collection */ - public function getTaxonCode() + public function getTaxonCodes() { - return $this->taxonCode; + return $this->taxonCodes; } /** - * @param string $taxonCode + * @param Collection $taxonCodes */ - public function setTaxonCode($taxonCode) + public function setTaxonCodes(Collection $taxonCodes) { - $this->taxonCode = $taxonCode; + $this->taxonCodes = $taxonCodes; } /** * @return Collection */ - public function getAttributes() + public function getAttributeValues() { - return $this->attributes; + return $this->attributeValues; } /** - * @param Collection $attributes + * @param Collection $attributeValues */ - public function setAttributes(Collection $attributes) + public function setAttributeValues(Collection $attributeValues) { - $this->attributes = $attributes; + $this->attributeValues = $attributeValues; } /** diff --git a/src/Document/TaxonCode.php b/src/Document/TaxonCode.php new file mode 100644 index 0000000..744a16d --- /dev/null +++ b/src/Document/TaxonCode.php @@ -0,0 +1,34 @@ +value = $value; + } + + /** + * @return string + */ + public function getValue() + { + return $this->value; + } +} diff --git a/src/Event/ProductCreated.php b/src/Event/ProductCreated.php new file mode 100644 index 0000000..d395d97 --- /dev/null +++ b/src/Event/ProductCreated.php @@ -0,0 +1,39 @@ +product = $product; + } + + /** + * @param ProductInterface $product + * + * @return self + */ + public static function occur(ProductInterface $product) + { + return new self($product); + } + + /** + * @return ProductInterface + */ + public function product() + { + return $this->product; + } +} diff --git a/src/EventListener/ProductPublisher.php b/src/EventListener/ProductPublisher.php new file mode 100644 index 0000000..7b6b5ce --- /dev/null +++ b/src/EventListener/ProductPublisher.php @@ -0,0 +1,35 @@ +eventBus = $eventBus; + } + + /** + * @param LifecycleEventArgs $event + */ + public function postPersist(LifecycleEventArgs $event) + { + $product = $event->getEntity(); + if ($product instanceof ProductInterface) { + $this->eventBus->handle(ProductCreated::occur($product)); + } + } +} diff --git a/src/Factory/ProductFactory.php b/src/Factory/ProductFactory.php new file mode 100644 index 0000000..65fc4c6 --- /dev/null +++ b/src/Factory/ProductFactory.php @@ -0,0 +1,99 @@ +isSimple()) { + throw new \InvalidArgumentException(sprintf( + 'Cannot create elastic search model from configurable product "%s" via this method.', + $syliusProduct->getCode() + )); + } + + /** @var ProductVariantInterface $productVariant */ + $productVariant = $syliusProduct->getVariants()->first(); + + /** @var ProductTranslationInterface|TranslationInterface $productTranslation */ + $productTranslation = $syliusProduct->getTranslation($locale->getCode()); + $channelPrice = $productVariant->getChannelPricingForChannel($channel); + $syliusProductAttributes = $syliusProduct->getAttributesByLocale( + $locale->getCode(), + $channel->getDefaultLocale()->getCode() + ); + $syliusProductTaxons = $syliusProduct->getProductTaxons(); + + $product = new Product(); + $price = new Price(); + $taxonCode = new TaxonCode(); + $taxonCode->setValue($syliusProduct->getMainTaxon()->getCode()); + + $price->setAmount($channelPrice->getPrice()); + $price->setCurrency($channel->getBaseCurrency()->getCode()); + + $product->setLocaleCode($locale->getCode()); + $product->setName($productTranslation->getName()); + $product->setDescription($productTranslation->getDescription()); + $product->setChannelCode($channel->getCode()); + $product->setPrice($price); + $product->setCode($syliusProduct->getCode()); + $product->setCreatedAt($syliusProduct->getCreatedAt()); + $product->setMainTaxonCode($taxonCode); + + $productTaxonCodes = []; + foreach ($syliusProductTaxons as $syliusProductTaxon) { + $productTaxonCode = new TaxonCode(); + $productTaxonCode->setValue($syliusProductTaxon->getTaxon()->getCode()); + $productTaxonCodes[] = $productTaxonCode; + } + $product->setTaxonCodes(new Collection($productTaxonCodes)); + + $productAttributeValues = []; + foreach ($syliusProductAttributes as $syliusProductAttributeValue) { + $productAttributeValue = new AttributeValue(); + $productAttributeValue->setCode($syliusProductAttributeValue->getCode()); + $productAttributeValue->setValue($syliusProductAttributeValue->getValue()); + + $attribute = new Attribute(); + $attribute->setCode($syliusProductAttributeValue->getAttribute()->getCode()); + $attribute->setName($syliusProductAttributeValue->getAttribute()->getName()); + $productAttributeValue->setAttribute($attribute); + + $productAttributeValues[] = $productAttributeValue; + } + $productAttributeValues = new Collection($productAttributeValues); + $product->setAttributeValues($productAttributeValues); + + return $product; + } +} diff --git a/src/Factory/ProductFactoryInterface.php b/src/Factory/ProductFactoryInterface.php new file mode 100644 index 0000000..01281ec --- /dev/null +++ b/src/Factory/ProductFactoryInterface.php @@ -0,0 +1,29 @@ +manager = $manager; + $this->productDocumentFactory = $productDocumentFactory; + } + + /** + * @param ProductCreated $event + */ + public function handleProductCreated(ProductCreated $event) + { + $product = $event->product(); + $channels = $product->getChannels(); + + /** @var ChannelInterface $channel */ + foreach ($channels as $channel) { + $locales = $channel->getLocales(); + foreach ($locales as $locale) { + $productDocument = $this->productDocumentFactory->createFromSyliusSimpleProductModel( + $product, + $locale, + $channel + ); + + $this->manager->persist($productDocument); + } + } + + $this->manager->commit(); + } +} diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index baffc93..f7c4c70 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -13,5 +13,16 @@ + + + + + + + + + + + diff --git a/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php b/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php index f029e9c..326348a 100644 --- a/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/ProductInMainTaxonQueryFactory.php @@ -19,6 +19,6 @@ public function create(array $parameters = []) throw new MissingQueryParameterException('taxon_code', get_class($this)); } - return new TermQuery('taxon_code', strtolower($parameters['taxon_code'])); + return new TermQuery('main_taxon_code.value', strtolower($parameters['taxon_code'])); } } diff --git a/tests/Application/app/AppKernel.php b/tests/Application/app/AppKernel.php index 1abd685..60c2617 100644 --- a/tests/Application/app/AppKernel.php +++ b/tests/Application/app/AppKernel.php @@ -19,6 +19,8 @@ public function registerBundles() new \FOS\OAuthServerBundle\FOSOAuthServerBundle(), // Required by SyliusAdminApiBundle new \Sylius\Bundle\AdminApiBundle\SyliusAdminApiBundle(), new \ONGR\ElasticsearchBundle\ONGRElasticsearchBundle(), + new \SimpleBus\SymfonyBridge\SimpleBusCommandBusBundle(), + new \SimpleBus\SymfonyBridge\SimpleBusEventBusBundle(), ]); } diff --git a/tests/Behat/Context/Setup/ProductContext.php b/tests/Behat/Context/Setup/ProductContext.php index c62c6f1..6c5512a 100644 --- a/tests/Behat/Context/Setup/ProductContext.php +++ b/tests/Behat/Context/Setup/ProductContext.php @@ -16,6 +16,7 @@ use ONGR\ElasticsearchBundle\Service\Manager; use Sylius\ElasticSearchPlugin\Document\Price; use Sylius\ElasticSearchPlugin\Document\Product; +use Sylius\ElasticSearchPlugin\Document\TaxonCode; final class ProductContext implements Context { @@ -37,9 +38,18 @@ public function __construct(Manager $manager) */ public function theStoreHasAboutMugsAndStickers($mugsNumber, $stickersNumber, $booksNumber) { - $this->generateProductsInTaxon($mugsNumber, 'mugs'); - $this->generateProductsInTaxon($stickersNumber, 'stickers'); - $this->generateProductsInTaxon($booksNumber, 'books'); + $mugsTaxonCode = new TaxonCode(); + $mugsTaxonCode->setValue('mugs'); + + $stickersTaxonCode = new TaxonCode(); + $stickersTaxonCode->setValue('stickers'); + + $booksTaxonCode = new TaxonCode(); + $booksTaxonCode->setValue('books'); + + $this->generateProductsInTaxon($mugsNumber, $mugsTaxonCode); + $this->generateProductsInTaxon($stickersNumber, $stickersTaxonCode); + $this->generateProductsInTaxon($booksNumber, $booksTaxonCode); } /** @@ -57,13 +67,13 @@ public function storeHasAProductPricedAt($productName, $price = 100, $channelCod /** * @param int $howMany - * @param string $taxonCode + * @param TaxonCode $taxonCode */ - private function generateProductsInTaxon($howMany, $taxonCode) + private function generateProductsInTaxon($howMany, TaxonCode $taxonCode) { for ($i = 0; $i < $howMany; $i++) { $product = new Product(); - $product->setTaxonCode($taxonCode); + $product->setMainTaxonCode($taxonCode); $product->setCode(uniqid()); $this->manager->persist($product); } diff --git a/tests/Event/ProductCreatedTest.php b/tests/Event/ProductCreatedTest.php new file mode 100644 index 0000000..65246e8 --- /dev/null +++ b/tests/Event/ProductCreatedTest.php @@ -0,0 +1,21 @@ +prophesize(ProductInterface::class); + $event = ProductCreated::occur($product->reveal()); + + $this->assertEquals($product->reveal(), $event->product()); + } +} diff --git a/tests/Factory/ProductFactoryTest.php b/tests/Factory/ProductFactoryTest.php new file mode 100644 index 0000000..f0b2668 --- /dev/null +++ b/tests/Factory/ProductFactoryTest.php @@ -0,0 +1,158 @@ +create(); + + $this->assertEquals(null, $product->getCode()); + $this->assertEquals(null, $product->getName()); + $this->assertEquals(null, $product->getLocaleCode()); + $this->assertEquals(new Collection, $product->getAttributeValues()); + $this->assertEquals(null, $product->getPrice()); + $this->assertEquals(null, $product->getChannelCode()); + $this->assertEquals(null, $product->getCreatedAt()); + $this->assertEquals(null, $product->getDescription()); + $this->assertEquals(new Collection, $product->getTaxonCodes()); + } + + /** + * @test + */ + public function it_creates_product_document_from_sylius_product_model() + { + $createdAt = \DateTime::createFromFormat(\DateTime::W3C, '2017-04-18T16:12:55+02:00'); + $syliusProductAttributeValue = new ProductAttributeValue(); + $syliusProductAttribute = new ProductAttribute(); + $syliusProductAttribute->setCurrentLocale('en_US'); + $syliusProductAttribute->setCode('red'); + $syliusProductAttribute->setName('Color red'); + $syliusProductAttributeValue->setLocaleCode('en_US'); + $syliusProductAttribute->setType(TextAttributeType::TYPE); + $syliusProductAttribute->setStorageType(TextAttributeType::TYPE); + $syliusProductAttributeValue->setAttribute($syliusProductAttribute); + $syliusProductAttributeValue->setValue('red'); + + $syliusTaxon = new Taxon(); + $syliusTaxon->setCode('tree'); + $syliusProductTaxon = new ProductTaxon(); + + $syliusLocale = new Locale(); + $syliusLocale->setCode('en_US'); + + $syliusProduct = new SyliusProduct(); + $syliusProductVariant = new ProductVariant(); + $channelPrice = new ChannelPricing(); + $syliusChannel = new Channel(); + $currency = new Currency(); + $currency->setCode('USD'); + + $syliusProductTaxon->setProduct($syliusProduct); + $syliusProductTaxon->setTaxon($syliusTaxon); + $channelPrice->setPrice(1000); + $channelPrice->setChannelCode('mobile'); + + $syliusChannel->setCode('mobile'); + $syliusChannel->setDefaultLocale($syliusLocale); + $syliusChannel->addLocale($syliusLocale); + $syliusChannel->addCurrency($currency); + $syliusChannel->setBaseCurrency($currency); + + $syliusProductVariant->addChannelPricing($channelPrice); + $syliusProduct->addVariant($syliusProductVariant); + $syliusProduct->addChannel($syliusChannel); + $syliusProduct->setMainTaxon($syliusTaxon); + $syliusProduct->addProductTaxon($syliusProductTaxon); + $syliusProduct->setCreatedAt($createdAt); + $syliusProduct->setCurrentLocale('en_US'); + $syliusProduct->setName('Banana'); + $syliusProduct->setDescription('Lorem ipsum'); + $syliusProduct->setCode('banana'); + $syliusProduct->addAttribute($syliusProductAttributeValue); + + $factory = new ProductFactory(); + /** @var Product $product */ + $product = $factory->createFromSyliusSimpleProductModel( + $syliusProduct, + $syliusLocale, + $syliusChannel + ); + + $taxonCode = new TaxonCode(); + $taxonCode->setValue('tree'); + + $productTaxonCode = new TaxonCode(); + $productTaxonCode->setValue('tree'); + + $productAttribute = new Attribute(); + $productAttribute->setCode('red'); + $productAttribute->setName('Color red'); + + $productAttributeValue = new AttributeValue(); + $productAttributeValue->setValue('red'); + $productAttributeValue->setCode('red'); + $productAttributeValue->setAttribute($productAttribute); + + $this->assertEquals('banana', $product->getCode()); + $this->assertEquals('Banana', $product->getName()); + $this->assertEquals('en_US', $product->getLocaleCode()); + $this->assertEquals( + new Collection([ + $productAttributeValue + ]), + $product->getAttributeValues() + ); + $this->assertEquals(1000, $product->getPrice()->getAmount()); + $this->assertEquals('USD', $product->getPrice()->getCurrency()); + $this->assertEquals('en_US', $product->getLocaleCode()); + $this->assertEquals('mobile', $product->getChannelCode()); + $this->assertEquals($createdAt, $product->getCreatedAt()); + $this->assertEquals('Lorem ipsum', $product->getDescription()); + $this->assertEquals($taxonCode, $product->getMainTaxonCode()); + $this->assertEquals(new Collection([$productTaxonCode]), $product->getTaxonCodes()); + } + + /** + * @test + * + * @expectedException \InvalidArgumentException + */ + public function it_cannot_create_product_document_from_configurable_product() + { + $factory = new ProductFactory(); + + $syliusProduct = new SyliusProduct(); + $syliusProduct->addVariant(new ProductVariant()); + $syliusProduct->addVariant(new ProductVariant()); + $syliusLocale = new Locale(); + $syliusChannel = new Channel(); + + $factory->createFromSyliusSimpleProductModel($syliusProduct, $syliusLocale, $syliusChannel); + } +} From 0f83a8ba97127bf3f9feb16183e48f5211f2a61d Mon Sep 17 00:00:00 2001 From: Arminek Date: Mon, 29 May 2017 08:15:41 +0200 Subject: [PATCH 6/6] [ElasticSearch] Define api end point --- .travis.yml | 3 +- README.md | 35 +++-------- composer.json | 3 +- ...iltering_list_of_products_by_taxon.feature | 10 +-- spec/EventListener/ProductPublisherSpec.php | 14 +++++ spec/Search/Criteria/CriteriaSpec.php | 8 +-- .../ProductHasOptionCodesFilterSpec.php | 27 -------- .../Filtering/ProductInChannelFilterSpec.php | 27 -------- .../ProductInPriceRangeFilterSpec.php | 32 ---------- .../Filtering/ProductInTaxonFilterSpec.php | 27 -------- spec/Search/Criteria/FilteringSpec.php | 4 +- spec/Search/Criteria/OrderingSpec.php | 8 +-- spec/Search/Criteria/PaginatingSpec.php | 18 +++--- spec/Search/Criteria/SearchPhraseSpec.php | 27 -------- ...ctHasMultipleOptionCodesApplicatorSpec.php | 62 ------------------ .../Filter/ProductInChannelApplicatorSpec.php | 17 ++++- .../ProductInPriceRangeApplicatorSpec.php | 15 ++++- .../Filter/ProductInTaxonApplicatorSpec.php | 15 ++++- .../MatchProductByNameApplicatorSpec.php | 25 ++++---- .../Sort/SortByFieldApplicatorSpec.php | 7 ++- .../MatchProductNameQueryFactorySpec.php | 2 +- src/Controller/SearchController.php | 24 ++++--- .../RegisterSearchCriteriaApplicatorPass.php | 6 +- src/EventListener/ProductPublisher.php | 4 +- src/Resources/config/routing.yml | 6 ++ src/Resources/config/services/controller.xml | 3 - .../services/search_criteria_applicator.xml | 15 ++--- src/Search/Criteria/Criteria.php | 24 +++---- src/Search/Criteria/Filtering.php | 2 +- .../Filtering/ProductHasOptionCodesFilter.php | 39 ------------ .../Filtering/ProductInChannelFilter.php | 30 --------- .../Filtering/ProductInPriceRangeFilter.php | 54 ---------------- .../Filtering/ProductInTaxonFilter.php | 30 --------- src/Search/Criteria/Ordering.php | 4 +- src/Search/Criteria/Paginating.php | 6 +- src/Search/Criteria/SearchPhrase.php | 39 ------------ ...roductHasMultipleOptionCodesApplicator.php | 42 ------------- .../Filter/ProductInChannelApplicator.php | 21 +++++-- .../Filter/ProductInPriceRangeApplicator.php | 29 ++++++--- .../Filter/ProductInTaxonApplicator.php | 24 +++++-- .../Query/MatchProductByNameApplicator.php | 39 +++++------- .../Applicator/SearchCriteriaApplicator.php | 52 --------------- .../SearchCriteriaApplicatorInterface.php | 12 +++- .../Applicator/Sort/SortByFieldApplicator.php | 18 ++++-- src/Search/Elastic/ElasticSearchEngine.php | 33 +++------- .../Query/MatchProductNameQueryFactory.php | 4 +- .../Factory/Sort/SortByFieldQueryFactory.php | 2 +- src/Search/SearchEngineInterface.php | 3 +- tests/Application/app/config/routing.yml | 2 +- .../Context/Domain/Shop/ProductContext.php | 63 +++++-------------- ...gisterSearchCriteriaApplicatorPassTest.php | 20 +----- 51 files changed, 278 insertions(+), 758 deletions(-) delete mode 100644 spec/Search/Criteria/Filtering/ProductHasOptionCodesFilterSpec.php delete mode 100644 spec/Search/Criteria/Filtering/ProductInChannelFilterSpec.php delete mode 100644 spec/Search/Criteria/Filtering/ProductInPriceRangeFilterSpec.php delete mode 100644 spec/Search/Criteria/Filtering/ProductInTaxonFilterSpec.php delete mode 100644 spec/Search/Criteria/SearchPhraseSpec.php delete mode 100644 spec/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicatorSpec.php delete mode 100644 src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php delete mode 100644 src/Search/Criteria/Filtering/ProductInChannelFilter.php delete mode 100644 src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php delete mode 100644 src/Search/Criteria/Filtering/ProductInTaxonFilter.php delete mode 100644 src/Search/Criteria/SearchPhrase.php delete mode 100644 src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php delete mode 100644 src/Search/Elastic/Applicator/SearchCriteriaApplicator.php diff --git a/.travis.yml b/.travis.yml index e0911d0..0e50c11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: php php: - 7.1 - - 5.6 jdk: - oraclejdk8 @@ -13,7 +12,7 @@ addons: - elasticsearch-5.x packages: - elasticsearch - - oracle-java8-installer + - oracle-java8-set-default services: - elasticsearch diff --git a/README.md b/README.md index b312c52..1a6849e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Sylius ElasticSearchBundle +Sylius ElasticSearchPlugin ========================== Elastic search for Sylius. [![Build status on Linux](https://img.shields.io/travis/Lakion/SyliusElasticSearchBundle/master.svg)](http://travis-ci.org/Lakion/SyliusELasticSearchBundle) @@ -8,12 +8,12 @@ Elastic search for Sylius. 1. Install it: ```bash - $ composer require lakion/sylius-elastic-search-bundle + $ composer require sylius/elastic-search-plugin ``` 2. Install elastic search server: ```bash - $ brew install elasticsearch@2.4 + $ brew install elasticsearch@5.0 ``` 3. Run elastic search server: @@ -25,8 +25,8 @@ Elastic search for Sylius. 4. Add this bundle to `AppKernel.php`: ```php - new \FOS\ElasticaBundle\FOSElasticaBundle(), - new \Lakion\SyliusElasticSearchBundle\LakionSyliusElasticSearchBundle(), + new \ONGR\ElasticsearchBundle\ONGRElasticsearchBundle(), + new \Lakion\SyliusElasticSearchBundle\SyliusElasticSearchPlugin(), ``` 5. Create/Setup database: @@ -37,37 +37,16 @@ Elastic search for Sylius. $ app/console syl:fix:lo ``` -6. Populate your elastic search server with command or your custom code: - - ```bash - $ app/console fos:elastic:pop - ``` - 7. Import config file in `app/config/config.yml` for default filter set configuration: ```yaml imports: - - { resource: "@LakionSyliusElasticSearchBundle/Resources/config/app/config.yml" } + - { resource: "@SyliusElasticSearchPlugin/Resources/config/app/config.yml" } ``` 8. Import routing files in `app/config/routing.yml`: ```yaml sylius_search: - resource: "@LakionSyliusElasticSearchBundle/Resources/config/routing.yml" - ``` - -8. Configuration reference: - - ```yaml - sylius_elastic_search: - filter_sets: - mugs: - filters: - product_options: - type: option - options: - code: mug_type - product_price: - type: price + resource: "@SyliusElasticSearchPlugin/Resources/config/routing.yml" ``` diff --git a/composer.json b/composer.json index 2ea254d..f374e9d 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ "sylius/sylius": "dev-master", "ongr/elasticsearch-dsl": "^5.0", "ongr/elasticsearch-bundle": "^5.0", - "simple-bus/symfony-bridge": "^4.1" + "simple-bus/symfony-bridge": "^4.1", + "beberlei/porpaginas": "^1.0" }, "require-dev": { "behat/behat": "^3.2", diff --git a/features/shop/product/searching/filtering_list_of_products_by_taxon.feature b/features/shop/product/searching/filtering_list_of_products_by_taxon.feature index cf1defb..d82a25e 100644 --- a/features/shop/product/searching/filtering_list_of_products_by_taxon.feature +++ b/features/shop/product/searching/filtering_list_of_products_by_taxon.feature @@ -5,24 +5,24 @@ Feature: Filtering list of products by taxon I want to be able to filter the products Background: - Given the store has 40 Mugs, 15 Stickers and 50 Books + Given the store has 3 Mugs, 2 Stickers and 5 Books @domain Scenario: Filtering products by book When I filter them by "books" taxon - Then I should see 50 products on the list + Then I should see 5 products on the list @domain Scenario: Filtering product by stickers When I filter them by "stickers" taxon - Then I should see 15 products on the list + Then I should see 2 products on the list @domain Scenario: Filtering product by mugs When I filter them by "mugs" taxon - Then I should see 40 products on the list + Then I should see 3 products on the list @domain Scenario: List of all products without filtering When I view the list of the products without filtering - Then I should see 105 products on the list + Then I should see 10 products on the list diff --git a/spec/EventListener/ProductPublisherSpec.php b/spec/EventListener/ProductPublisherSpec.php index 2bf64a8..366ec20 100644 --- a/spec/EventListener/ProductPublisherSpec.php +++ b/spec/EventListener/ProductPublisherSpec.php @@ -24,6 +24,7 @@ function it_is_initializable() function it_publishes_product_event(MessageBus $eventBus, LifecycleEventArgs $event, ProductInterface $product) { + $product->isSimple()->willReturn(true); $event->getEntity()->willReturn($product); $eventBus->handle(ProductCreated::occur($product->getWrappedObject()))->shouldBeCalled(); @@ -39,4 +40,17 @@ function it_does_not_publish_product_event_if_entity_is_not_a_product(MessageBus $this->postPersist($event); } + + function it_does_not_publish_product_event_if_entity_is_not_a_simple_product( + MessageBus $eventBus, + LifecycleEventArgs $event, + ProductInterface $product + ) { + $product->isSimple()->willReturn(false); + $event->getEntity()->willReturn($product); + + $eventBus->handle(Argument::any())->shouldNotBeCalled(); + + $this->postPersist($event); + } } diff --git a/spec/Search/Criteria/CriteriaSpec.php b/spec/Search/Criteria/CriteriaSpec.php index d1a56eb..76f515b 100644 --- a/spec/Search/Criteria/CriteriaSpec.php +++ b/spec/Search/Criteria/CriteriaSpec.php @@ -27,20 +27,20 @@ function it_is_created_from_query_parameters_and_resource_alias() 'option' => 'red', ]]); - $this->getResourceAlias()->shouldReturn('sylius.product'); - $this->getFiltering()->shouldBeLike(Filtering::fromQueryParameters([ + $this->documentClass()->shouldReturn('sylius.product'); + $this->filtering()->shouldBeLike(Filtering::fromQueryParameters([ 'page' => 2, 'per_page' => 50, 'sort' => '-price', 'option' => 'red', ])); - $this->getPaginating()->shouldBeLike(Paginating::fromQueryParameters([ + $this->paginating()->shouldBeLike(Paginating::fromQueryParameters([ 'page' => 2, 'per_page' => 50, 'sort' => '-price', 'option' => 'red', ])); - $this->getOrdering()->shouldBeLike(Ordering::fromQueryParameters([ + $this->ordering()->shouldBeLike(Ordering::fromQueryParameters([ 'page' => 2, 'per_page' => 50, 'sort' => '-price', diff --git a/spec/Search/Criteria/Filtering/ProductHasOptionCodesFilterSpec.php b/spec/Search/Criteria/Filtering/ProductHasOptionCodesFilterSpec.php deleted file mode 100644 index a03866d..0000000 --- a/spec/Search/Criteria/Filtering/ProductHasOptionCodesFilterSpec.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ -final class ProductHasOptionCodesFilterSpec extends ObjectBehavior -{ - function let() - { - $this->beConstructedWith(['mug_type_double', 'mug_type_small']); - } - - function it_is_initializable() - { - $this->shouldHaveType(ProductHasOptionCodesFilter::class); - } - - function it_has_immutable_option_codes() - { - $this->getCodes()->shouldReturn(['mug_type_double', 'mug_type_small']); - } -} diff --git a/spec/Search/Criteria/Filtering/ProductInChannelFilterSpec.php b/spec/Search/Criteria/Filtering/ProductInChannelFilterSpec.php deleted file mode 100644 index e04d6bb..0000000 --- a/spec/Search/Criteria/Filtering/ProductInChannelFilterSpec.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ -final class ProductInChannelFilterSpec extends ObjectBehavior -{ - function let() - { - $this->beConstructedWith('web_uk'); - } - - function it_is_initializable() - { - $this->shouldHaveType(ProductInChannelFilter::class); - } - - function it_has_immutable_channel_code() - { - $this->getChannelCode()->shouldReturn('web_uk'); - } -} diff --git a/spec/Search/Criteria/Filtering/ProductInPriceRangeFilterSpec.php b/spec/Search/Criteria/Filtering/ProductInPriceRangeFilterSpec.php deleted file mode 100644 index c3bd395..0000000 --- a/spec/Search/Criteria/Filtering/ProductInPriceRangeFilterSpec.php +++ /dev/null @@ -1,32 +0,0 @@ - - */ -final class ProductInPriceRangeFilterSpec extends ObjectBehavior -{ - function let() - { - $this->beConstructedWith(100, 300); - } - - function it_is_initializable() - { - $this->shouldHaveType(ProductInPriceRangeFilter::class); - } - - function it_has_immutable_grater_than() - { - $this->getGraterThan()->shouldReturn(100); - } - - function it_has_immutable_less_than() - { - $this->getLessThan()->shouldReturn(300); - } -} diff --git a/spec/Search/Criteria/Filtering/ProductInTaxonFilterSpec.php b/spec/Search/Criteria/Filtering/ProductInTaxonFilterSpec.php deleted file mode 100644 index c8d222a..0000000 --- a/spec/Search/Criteria/Filtering/ProductInTaxonFilterSpec.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ -final class ProductInTaxonFilterSpec extends ObjectBehavior -{ - function let() - { - $this->beConstructedWith('mugs'); - } - - function it_is_initializable() - { - $this->shouldHaveType(ProductInTaxonFilter::class); - } - - function it_has_immutable_taxon_code() - { - $this->getTaxonCode()->shouldReturn('mugs'); - } -} diff --git a/spec/Search/Criteria/FilteringSpec.php b/spec/Search/Criteria/FilteringSpec.php index f407335..37af4c8 100644 --- a/spec/Search/Criteria/FilteringSpec.php +++ b/spec/Search/Criteria/FilteringSpec.php @@ -22,7 +22,7 @@ function it_can_be_created_from_query_parameters() 'size' => 's', ]]); - $this->getFields()->shouldReturn(['option' => 'red', 'size' => 's',]); + $this->fields()->shouldReturn(['option' => 'red', 'size' => 's',]); } function it_removes_page_per_page_and_sort_attributes_from_query_parameters() @@ -35,6 +35,6 @@ function it_removes_page_per_page_and_sort_attributes_from_query_parameters() 'limit' => 50, ]]); - $this->getFields()->shouldReturn(['option' => 'blue', 'size' => 'm',]); + $this->fields()->shouldReturn(['option' => 'blue', 'size' => 'm',]); } } diff --git a/spec/Search/Criteria/OrderingSpec.php b/spec/Search/Criteria/OrderingSpec.php index 2545a5d..55099c0 100644 --- a/spec/Search/Criteria/OrderingSpec.php +++ b/spec/Search/Criteria/OrderingSpec.php @@ -21,8 +21,8 @@ function it_can_be_created_from_query_parameters_with_default_direction() 'sort' => 'code', ]]); - $this->getField()->shouldReturn('code.raw'); - $this->getDirection()->shouldReturn('asc'); + $this->field()->shouldReturn('code.raw'); + $this->direction()->shouldReturn('asc'); } function it_can_be_created_from_query_parameters() @@ -31,7 +31,7 @@ function it_can_be_created_from_query_parameters() 'sort' => '-code', ]]); - $this->getField()->shouldReturn('code.raw'); - $this->getDirection()->shouldReturn('desc'); + $this->field()->shouldReturn('code.raw'); + $this->direction()->shouldReturn('desc'); } } diff --git a/spec/Search/Criteria/PaginatingSpec.php b/spec/Search/Criteria/PaginatingSpec.php index c3f7d8f..6b72f7e 100644 --- a/spec/Search/Criteria/PaginatingSpec.php +++ b/spec/Search/Criteria/PaginatingSpec.php @@ -19,9 +19,9 @@ function it_can_be_created_form_query_parameters_with_default_values_if_paramete { $this->beConstructedThrough('fromQueryParameters', [[]]); - $this->getCurrentPage()->shouldReturn(1); - $this->getItemsPerPage()->shouldReturn(10); - $this->getOffset()->shouldReturn(0); + $this->currentPage()->shouldReturn(1); + $this->itemsPerPage()->shouldReturn(10); + $this->offset()->shouldReturn(0); } function it_can_be_created_from_query_parameters_with_default_values_if_parameters_are_not_valid() @@ -31,9 +31,9 @@ function it_can_be_created_from_query_parameters_with_default_values_if_paramete 'limit' => -100, ]]); - $this->getCurrentPage()->shouldReturn(1); - $this->getItemsPerPage()->shouldReturn(10); - $this->getOffset()->shouldReturn(0); + $this->currentPage()->shouldReturn(1); + $this->itemsPerPage()->shouldReturn(10); + $this->offset()->shouldReturn(0); } function it_can_be_created_from_query_parameters() @@ -43,8 +43,8 @@ function it_can_be_created_from_query_parameters() 'limit' => 50, ]]); - $this->getCurrentPage()->shouldReturn(2); - $this->getItemsPerPage()->shouldReturn(50); - $this->getOffset()->shouldReturn(50); + $this->currentPage()->shouldReturn(2); + $this->itemsPerPage()->shouldReturn(50); + $this->offset()->shouldReturn(50); } } diff --git a/spec/Search/Criteria/SearchPhraseSpec.php b/spec/Search/Criteria/SearchPhraseSpec.php deleted file mode 100644 index 8731b41..0000000 --- a/spec/Search/Criteria/SearchPhraseSpec.php +++ /dev/null @@ -1,27 +0,0 @@ - - */ -final class SearchPhraseSpec extends ObjectBehavior -{ - function let() - { - $this->beConstructedWith('Mug'); - } - - function it_is_initializable() - { - $this->shouldHaveType(SearchPhrase::class); - } - - function it_has_immutable_search_phrase() - { - $this->getPhrase()->shouldReturn('Mug'); - } -} diff --git a/spec/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicatorSpec.php b/spec/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicatorSpec.php deleted file mode 100644 index 3e87e91..0000000 --- a/spec/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicatorSpec.php +++ /dev/null @@ -1,62 +0,0 @@ - - */ -final class ProductHasMultipleOptionCodesApplicatorSpec extends ObjectBehavior -{ - function let(QueryFactoryInterface $productHasOptionCodeQueryFactory) - { - $this->beConstructedWith($productHasOptionCodeQueryFactory); - } - - function it_is_initializable() - { - $this->shouldHaveType(ProductHasMultipleOptionCodesApplicator::class); - } - - function it_is_criteria_search_applicator() - { - $this->shouldImplement(SearchCriteriaApplicatorInterface::class); - } - - function it_applies_search_query_for_multiple_product_options( - QueryFactoryInterface $productHasOptionCodeQueryFactory, - TermQuery $mediumMugTermQuery, - TermQuery $stickerSizeTermQuery, - Search $search - ) { - $criteria = new ProductHasOptionCodesFilter(['medium_mug', 'sticker_size_1']); - $productHasOptionCodeQueryFactory->create(['option_value_code' => 'medium_mug'])->willReturn($mediumMugTermQuery); - $productHasOptionCodeQueryFactory->create(['option_value_code' => 'sticker_size_1'])->willReturn($stickerSizeTermQuery); - - $search->addPostFilter($mediumMugTermQuery, BoolQuery::SHOULD)->shouldBeCalled(); - $search->addPostFilter($stickerSizeTermQuery, BoolQuery::SHOULD)->shouldBeCalled(); - - $this->apply($criteria, $search); - } - - function it_applies_search_query_for_single_product_option( - QueryFactoryInterface $productHasOptionCodeQueryFactory, - TermQuery $mediumMugTermQuery, - Search $search - ) { - $criteria = new ProductHasOptionCodesFilter(['medium_mug']); - $productHasOptionCodeQueryFactory->create(['option_value_code' => 'medium_mug'])->willReturn($mediumMugTermQuery); - - $search->addPostFilter($mediumMugTermQuery, BoolQuery::SHOULD)->shouldBeCalled(); - - $this->apply($criteria, $search); - } -} diff --git a/spec/Search/Elastic/Applicator/Filter/ProductInChannelApplicatorSpec.php b/spec/Search/Elastic/Applicator/Filter/ProductInChannelApplicatorSpec.php index 0a5c868..7444143 100644 --- a/spec/Search/Elastic/Applicator/Filter/ProductInChannelApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Filter/ProductInChannelApplicatorSpec.php @@ -4,6 +4,8 @@ use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; use ONGR\ElasticsearchDSL\Query\Joining\NestedQuery; +use Sylius\ElasticSearchPlugin\Document\Product; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInChannelFilter; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter\ProductInChannelApplicator; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; @@ -36,10 +38,21 @@ function it_applies_search_criteria_with_channel_code( Search $search, NestedQuery $nestedQuery ) { - $criteria = new ProductInChannelFilter('web'); - $productInChannelQueryFactory->create(['channel_code' => 'web'])->willReturn($nestedQuery); + $criteria = Criteria::fromQueryParameters(Product::class, ['channel_code' => 'web']); + $productInChannelQueryFactory->create($criteria->filtering()->fields())->willReturn($nestedQuery); $search->addPostFilter($nestedQuery, BoolQuery::MUST)->shouldBeCalled(); $this->apply($criteria, $search); } + + function it_supports_channel_code_parameter() + { + $criteria = Criteria::fromQueryParameters(Product::class, ['channel_code' => 'web']); + + $this->supports($criteria)->shouldReturn(true); + + $criteria = Criteria::fromQueryParameters(Product::class, ['taxon_code' => 'tree']); + + $this->supports($criteria)->shouldReturn(false); + } } diff --git a/spec/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicatorSpec.php b/spec/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicatorSpec.php index 46011c9..1b57b79 100644 --- a/spec/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicatorSpec.php @@ -4,6 +4,8 @@ use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery; +use Sylius\ElasticSearchPlugin\Document\Product; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInPriceRangeFilter; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter\ProductInPriceRangeApplicator; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; @@ -33,10 +35,19 @@ function it_is_search_criteria_applicator() function it_applies_search_criteria_for_given_query(QueryFactoryInterface $productInPriceRangeQueryFactory, Search $search, TermQuery $termQuery) { - $criteria = new ProductInPriceRangeFilter(20, 50); - $productInPriceRangeQueryFactory->create(['product_price_range' => ['grater_than' => 20, 'less_than' => 50]])->willReturn($termQuery); + $criteria = Criteria::fromQueryParameters(Product::class, ['product_price_range' => ['grater_than' => 20, 'less_than' => 50]]); + $productInPriceRangeQueryFactory->create($criteria->filtering()->fields())->willReturn($termQuery); $search->addPostFilter($termQuery, BoolQuery::MUST)->shouldBeCalled(); $this->apply($criteria, $search); } + + function it_supports_product_price_range_parameter() + { + $criteria = Criteria::fromQueryParameters(Product::class, ['product_price_range' => ['grater_than' => 20, 'less_than' => 50]]); + $this->supports($criteria)->shouldReturn(true); + + $criteria = Criteria::fromQueryParameters(Product::class, []); + $this->supports($criteria)->shouldReturn(false); + } } diff --git a/spec/Search/Elastic/Applicator/Filter/ProductInTaxonApplicatorSpec.php b/spec/Search/Elastic/Applicator/Filter/ProductInTaxonApplicatorSpec.php index a4e7439..2605ccd 100644 --- a/spec/Search/Elastic/Applicator/Filter/ProductInTaxonApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Filter/ProductInTaxonApplicatorSpec.php @@ -4,6 +4,8 @@ use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery; +use Sylius\ElasticSearchPlugin\Document\Product; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInTaxonFilter; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter\ProductInTaxonApplicator; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; @@ -36,12 +38,21 @@ function it_applies_search_query_for_given_criteria( TermQuery $termQuery, Search $search ) { - $criteria = new ProductInTaxonFilter('mugs'); + $criteria = Criteria::fromQueryParameters(Product::class, ['taxon_code' => 'mugs']); - $productInMainTaxon->create(['taxon_code' => 'mugs'])->willReturn($termQuery); + $productInMainTaxon->create($criteria->filtering()->fields())->willReturn($termQuery); $search->addPostFilter($termQuery, BoolQuery::SHOULD)->shouldBeCalled(); $this->apply($criteria, $search); } + + function it_supports_taxon_code_paramter() + { + $criteria = Criteria::fromQueryParameters(Product::class, ['taxon_code' => 'mugs']); + $this->supports($criteria)->shouldReturn(true); + + $criteria = Criteria::fromQueryParameters(Product::class, []); + $this->supports($criteria)->shouldReturn(false); + } } diff --git a/spec/Search/Elastic/Applicator/Query/MatchProductByNameApplicatorSpec.php b/spec/Search/Elastic/Applicator/Query/MatchProductByNameApplicatorSpec.php index 3b0356f..93d4e8c 100644 --- a/spec/Search/Elastic/Applicator/Query/MatchProductByNameApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Query/MatchProductByNameApplicatorSpec.php @@ -3,6 +3,8 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Query; use ONGR\ElasticsearchDSL\Query\FullText\MatchQuery; +use Sylius\ElasticSearchPlugin\Document\Product; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\Criteria\SearchPhrase; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Query\MatchProductByNameApplicator; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; @@ -16,9 +18,9 @@ */ final class MatchProductByNameApplicatorSpec extends ObjectBehavior { - function let(QueryFactoryInterface $matchProductNameQueryFactory, QueryFactoryInterface $emptyQueryFactory) + function let(QueryFactoryInterface $matchProductNameQueryFactory) { - $this->beConstructedWith($matchProductNameQueryFactory, $emptyQueryFactory); + $this->beConstructedWith($matchProductNameQueryFactory); } function it_is_initializable() @@ -36,22 +38,19 @@ function it_applies_match_product_by_name_query( MatchQuery $matchQuery, Search $search ) { - $criteria = new SearchPhrase('banana'); - $matchProductNameQueryFactory->create(['phrase' => 'banana'])->willReturn($matchQuery); + $criteria = Criteria::fromQueryParameters(Product::class, ['search' => 'banana']); + $matchProductNameQueryFactory->create($criteria->filtering()->fields())->willReturn($matchQuery); $search->addQuery($matchQuery)->shouldBeCalled(); $this->apply($criteria, $search); } - function it_applies_match_all_for_empty_search_phrase( - QueryFactoryInterface $emptyQueryFactory, - MatchAllQuery $matchAllQuery, - Search $search - ) { - $criteria = new SearchPhrase(''); - $emptyQueryFactory->create()->willReturn($matchAllQuery); - $search->addQuery($matchAllQuery)->shouldBeCalled(); + function it_supports_search_parameter() + { + $criteria = Criteria::fromQueryParameters(Product::class, ['search' => 'banana']); + $this->supports($criteria)->shouldReturn(true); - $this->apply($criteria, $search); + $criteria = Criteria::fromQueryParameters(Product::class, []); + $this->supports($criteria)->shouldReturn(false); } } diff --git a/spec/Search/Elastic/Applicator/Sort/SortByFieldApplicatorSpec.php b/spec/Search/Elastic/Applicator/Sort/SortByFieldApplicatorSpec.php index ba69640..8395a8a 100644 --- a/spec/Search/Elastic/Applicator/Sort/SortByFieldApplicatorSpec.php +++ b/spec/Search/Elastic/Applicator/Sort/SortByFieldApplicatorSpec.php @@ -2,7 +2,8 @@ namespace spec\Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Sort; -use Sylius\ElasticSearchPlugin\Search\Criteria\Ordering; +use Sylius\ElasticSearchPlugin\Document\Product; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Sort\SortByFieldApplicator; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Sort\SortFactoryInterface; @@ -35,8 +36,8 @@ function it_applies_sort_query_to_search_with_given_sorting( Search $search, FieldSort $fieldSort ) { - $criteria = Ordering::fromQueryParameters(['sort' => '-name']); - $sortByFieldSortFactory->create($criteria)->willReturn($fieldSort); + $criteria = Criteria::fromQueryParameters(Product::class, ['sort' => '-name']); + $sortByFieldSortFactory->create($criteria->ordering())->willReturn($fieldSort); $search->addSort($fieldSort)->shouldBeCalled(); $this->apply($criteria, $search); diff --git a/spec/Search/Elastic/Factory/Query/MatchProductNameQueryFactorySpec.php b/spec/Search/Elastic/Factory/Query/MatchProductNameQueryFactorySpec.php index 77200bd..48f2bca 100644 --- a/spec/Search/Elastic/Factory/Query/MatchProductNameQueryFactorySpec.php +++ b/spec/Search/Elastic/Factory/Query/MatchProductNameQueryFactorySpec.php @@ -25,7 +25,7 @@ function it_is_query_factory() function it_creates_match_query_with_name_field_by_default() { - $this->create(['phrase' => 'banana'])->shouldBeLike(new MatchQuery('name', 'banana')); + $this->create(['search' => 'banana'])->shouldBeLike(new MatchQuery('name', 'banana')); } function it_cannot_be_created_without_search_parameter() diff --git a/src/Controller/SearchController.php b/src/Controller/SearchController.php index 32b8e91..3926991 100644 --- a/src/Controller/SearchController.php +++ b/src/Controller/SearchController.php @@ -11,8 +11,8 @@ namespace Sylius\ElasticSearchPlugin\Controller; -use FOS\RestBundle\View\ConfigurableViewHandlerInterface; use FOS\RestBundle\View\View; +use FOS\RestBundle\View\ViewHandlerInterface; use Sylius\ElasticSearchPlugin\Document\Product; use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\SearchEngineInterface; @@ -25,7 +25,7 @@ final class SearchController { /** - * @var ConfigurableViewHandlerInterface + * @var ViewHandlerInterface */ private $restViewHandler; @@ -35,10 +35,10 @@ final class SearchController private $searchEngine; /** - * @param ConfigurableViewHandlerInterface $restViewHandler + * @param ViewHandlerInterface $restViewHandler * @param SearchEngineInterface $searchEngine */ - public function __construct(ConfigurableViewHandlerInterface $restViewHandler, SearchEngineInterface $searchEngine) + public function __construct(ViewHandlerInterface $restViewHandler, SearchEngineInterface $searchEngine) { $this->restViewHandler = $restViewHandler; $this->searchEngine = $searchEngine; @@ -49,15 +49,19 @@ public function __construct(ConfigurableViewHandlerInterface $restViewHandler, S * * @return Response */ - public function searchAction(Request $request) + public function __invoke(Request $request) { - $content = $request->getContent(); - $criteria = Criteria::fromQueryParameters(Product::class, json_decode($content, true)); + $content = json_decode($request->getContent(), true); - $result = $this->searchEngine->match($criteria); + if (null === $content) { + $content = $request->query->all(); + } + + $criteria = Criteria::fromQueryParameters(Product::class, $content); - $view = View::create($result); + $result = $this->searchEngine->match($criteria); + $page = $result->take($criteria->paginating()->offset(), $criteria->paginating()->itemsPerPage()); - return $this->restViewHandler->handle($view); + return $this->restViewHandler->handle(View::create($page, Response::HTTP_OK)); } } diff --git a/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php b/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php index 0d27e1d..06cc4d3 100644 --- a/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php +++ b/src/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPass.php @@ -30,12 +30,8 @@ public function process(ContainerBuilder $container) } foreach ($container->findTaggedServiceIds('search_criteria_applicator') as $taggedServiceId => $taggedServiceConfig) { - if (!isset($taggedServiceConfig[0]['applies'])) { - throw new \InvalidArgumentException(sprintf('Applicator "%s" does not have applies attribute', $taggedServiceId)); - } - $engineDefinition = $container->getDefinition('sylius_elastic_search.search.elastic_engine'); - $engineDefinition->addMethodCall('addSearchCriteriaApplicator', [new Reference($taggedServiceId), $taggedServiceConfig[0]['applies']]); + $engineDefinition->addMethodCall('addSearchCriteriaApplicator', [new Reference($taggedServiceId)]); } } } diff --git a/src/EventListener/ProductPublisher.php b/src/EventListener/ProductPublisher.php index 7b6b5ce..1fcc351 100644 --- a/src/EventListener/ProductPublisher.php +++ b/src/EventListener/ProductPublisher.php @@ -29,7 +29,9 @@ public function postPersist(LifecycleEventArgs $event) { $product = $event->getEntity(); if ($product instanceof ProductInterface) { - $this->eventBus->handle(ProductCreated::occur($product)); + if ($product->isSimple()) { + $this->eventBus->handle(ProductCreated::occur($product)); + } } } } diff --git a/src/Resources/config/routing.yml b/src/Resources/config/routing.yml index e69de29..cb9fb34 100644 --- a/src/Resources/config/routing.yml +++ b/src/Resources/config/routing.yml @@ -0,0 +1,6 @@ +sylius_shop_search: + path: /search + methods: [GET] + defaults: + _controller: sylius_elastic_search.controller.search + _format: json diff --git a/src/Resources/config/services/controller.xml b/src/Resources/config/services/controller.xml index 75272b8..abfbc3b 100644 --- a/src/Resources/config/services/controller.xml +++ b/src/Resources/config/services/controller.xml @@ -8,9 +8,6 @@ - - - diff --git a/src/Resources/config/services/search_criteria_applicator.xml b/src/Resources/config/services/search_criteria_applicator.xml index a80f4c9..f8a3bfe 100644 --- a/src/Resources/config/services/search_criteria_applicator.xml +++ b/src/Resources/config/services/search_criteria_applicator.xml @@ -5,31 +5,26 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - - - + - + - + - + - - + diff --git a/src/Search/Criteria/Criteria.php b/src/Search/Criteria/Criteria.php index ad4032a..e0f95ba 100644 --- a/src/Search/Criteria/Criteria.php +++ b/src/Search/Criteria/Criteria.php @@ -10,7 +10,7 @@ final class Criteria /** * @var string */ - private $resourceAlias; + private $documentClass; /** * @var Paginating @@ -28,46 +28,46 @@ final class Criteria private $filtering; /** - * @param string $resourceAlias + * @param string $documentClass * @param Paginating $paginating * @param Ordering $ordering * @param Filtering $filtering */ - private function __construct($resourceAlias, Paginating $paginating, Ordering $ordering, Filtering $filtering) + private function __construct($documentClass, Paginating $paginating, Ordering $ordering, Filtering $filtering) { - $this->resourceAlias = $resourceAlias; + $this->documentClass = $documentClass; $this->paginating = $paginating; $this->ordering = $ordering; $this->filtering = $filtering; } /** - * @param $resourceAlias + * @param string $documentClass * @param array $parameters * * @return Criteria */ - public static function fromQueryParameters($resourceAlias, array $parameters) + public static function fromQueryParameters($documentClass, array $parameters) { $paginating = Paginating::fromQueryParameters($parameters); $ordering = Ordering::fromQueryParameters($parameters); $filtering = Filtering::fromQueryParameters($parameters); - return new self($resourceAlias, $paginating, $ordering, $filtering); + return new self($documentClass, $paginating, $ordering, $filtering); } /** * @return string */ - public function getResourceAlias() + public function documentClass() { - return $this->resourceAlias; + return $this->documentClass; } /** * @return Paginating */ - public function getPaginating() + public function paginating() { return $this->paginating; } @@ -75,7 +75,7 @@ public function getPaginating() /** * @return Ordering */ - public function getOrdering() + public function ordering() { return $this->ordering; } @@ -83,7 +83,7 @@ public function getOrdering() /** * @return Filtering */ - public function getFiltering() + public function filtering() { return $this->filtering; } diff --git a/src/Search/Criteria/Filtering.php b/src/Search/Criteria/Filtering.php index 26152df..b372504 100644 --- a/src/Search/Criteria/Filtering.php +++ b/src/Search/Criteria/Filtering.php @@ -39,7 +39,7 @@ public static function fromQueryParameters(array $queryParameters) /** * @return array */ - public function getFields() + public function fields() { return $this->fields; } diff --git a/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php b/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php deleted file mode 100644 index 8033095..0000000 --- a/src/Search/Criteria/Filtering/ProductHasOptionCodesFilter.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ -final class ProductHasOptionCodesFilter -{ - /** - * @var array - */ - private $codes; - - /** - * @param array $codes - */ - public function __construct(array $codes) - { - $this->codes = $codes; - } - - /** - * @return array - */ - public function getCodes() - { - return $this->codes; - } -} diff --git a/src/Search/Criteria/Filtering/ProductInChannelFilter.php b/src/Search/Criteria/Filtering/ProductInChannelFilter.php deleted file mode 100644 index 699cc6f..0000000 --- a/src/Search/Criteria/Filtering/ProductInChannelFilter.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ -final class ProductInChannelFilter -{ - /** - * @var string - */ - private $channelCode; - - /** - * @param string $channelCode - */ - public function __construct($channelCode) - { - $this->channelCode = $channelCode; - } - - /** - * @return string - */ - public function getChannelCode() - { - return $this->channelCode; - } -} diff --git a/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php b/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php deleted file mode 100644 index b84a908..0000000 --- a/src/Search/Criteria/Filtering/ProductInPriceRangeFilter.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ -final class ProductInPriceRangeFilter -{ - /** - * @var int - */ - private $graterThan; - - /** - * @var int - */ - private $lessThan; - - /** - * @param int $graterThan - * @param int $lessThan - */ - public function __construct($graterThan, $lessThan) - { - $this->graterThan = $graterThan; - $this->lessThan = $lessThan; - } - - /** - * @return int - */ - public function getGraterThan() - { - return $this->graterThan; - } - - /** - * @return int - */ - public function getLessThan() - { - return $this->lessThan; - } -} diff --git a/src/Search/Criteria/Filtering/ProductInTaxonFilter.php b/src/Search/Criteria/Filtering/ProductInTaxonFilter.php deleted file mode 100644 index ebb828d..0000000 --- a/src/Search/Criteria/Filtering/ProductInTaxonFilter.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ -final class ProductInTaxonFilter -{ - /** - * @var string - */ - private $taxonCode; - - /** - * @param string $taxonCode - */ - public function __construct($taxonCode) - { - $this->taxonCode = $taxonCode; - } - - /** - * @return string - */ - public function getTaxonCode() - { - return $this->taxonCode; - } -} diff --git a/src/Search/Criteria/Ordering.php b/src/Search/Criteria/Ordering.php index 5d01ccd..ac0e884 100644 --- a/src/Search/Criteria/Ordering.php +++ b/src/Search/Criteria/Ordering.php @@ -53,7 +53,7 @@ public static function fromQueryParameters(array $parameters) /** * @return string */ - public function getField() + public function field() { return $this->field; } @@ -61,7 +61,7 @@ public function getField() /** * @return string */ - public function getDirection() + public function direction() { return $this->direction; } diff --git a/src/Search/Criteria/Paginating.php b/src/Search/Criteria/Paginating.php index 7ed0687..78cdfce 100644 --- a/src/Search/Criteria/Paginating.php +++ b/src/Search/Criteria/Paginating.php @@ -60,7 +60,7 @@ public static function fromQueryParameters(array $parameters) /** * @return int */ - public function getCurrentPage() + public function currentPage() { return $this->currentPage; } @@ -68,7 +68,7 @@ public function getCurrentPage() /** * @return int */ - public function getItemsPerPage() + public function itemsPerPage() { return $this->itemsPerPage; } @@ -76,7 +76,7 @@ public function getItemsPerPage() /** * @return int */ - public function getOffset() + public function offset() { return $this->offset; } diff --git a/src/Search/Criteria/SearchPhrase.php b/src/Search/Criteria/SearchPhrase.php deleted file mode 100644 index 828d201..0000000 --- a/src/Search/Criteria/SearchPhrase.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ -final class SearchPhrase -{ - /** - * @var string - */ - private $phrase; - - /** - * @param string $phrase - */ - public function __construct($phrase) - { - $this->phrase = $phrase; - } - - /** - * @return string - */ - public function getPhrase() - { - return $this->phrase; - } -} diff --git a/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php deleted file mode 100644 index 38efc25..0000000 --- a/src/Search/Elastic/Applicator/Filter/ProductHasMultipleOptionCodesApplicator.php +++ /dev/null @@ -1,42 +0,0 @@ - - */ -final class ProductHasMultipleOptionCodesApplicator extends SearchCriteriaApplicator -{ - /** - * @var QueryFactoryInterface - */ - private $productHasOptionCodeQueryFactory; - - /** - * {@inheritdoc} - */ - public function __construct(QueryFactoryInterface $productHasOptionCodeQueryFactory) - { - $this->productHasOptionCodeQueryFactory = $productHasOptionCodeQueryFactory; - } - - /** - * @param ProductHasOptionCodesFilter $codesFilter - * @param Search $search - */ - public function applyProductHasOptionCodesFilter(ProductHasOptionCodesFilter $codesFilter, Search $search) - { - foreach ($codesFilter->getCodes() as $code) { - $search->addPostFilter( - $this->productHasOptionCodeQueryFactory->create(['option_value_code' => $code]), - BoolQuery::SHOULD - ); - } - } -} diff --git a/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php index 8a8978b..962ff49 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductInChannelApplicator.php @@ -3,15 +3,15 @@ namespace Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter; use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; -use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInChannelFilter; -use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicator; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; +use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; use ONGR\ElasticsearchDSL\Search; /** * @author Arkadiusz Krakowiak */ -final class ProductInChannelApplicator extends SearchCriteriaApplicator +final class ProductInChannelApplicator implements SearchCriteriaApplicatorInterface { /** * @var QueryFactoryInterface @@ -29,8 +29,19 @@ public function __construct(QueryFactoryInterface $productInChannelQueryFactory) /** * {@inheritdoc} */ - public function applyProductInChannelFilter(ProductInChannelFilter $inChannelFilter, Search $search) + public function apply(Criteria $criteria, Search $search) { - $search->addPostFilter($this->productInChannelQueryFactory->create(['channel_code' => $inChannelFilter->getChannelCode()]), BoolQuery::MUST); + $search->addPostFilter($this->productInChannelQueryFactory->create($criteria->filtering()->fields()), BoolQuery::MUST); + } + + /** + * {@inheritdoc} + */ + public function supports(Criteria $criteria) + { + return + array_key_exists('channel_code', $criteria->filtering()->fields()) && + null !== $criteria->filtering()->fields()['channel_code'] + ; } } diff --git a/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php index 532ccd4..de9256d 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductInPriceRangeApplicator.php @@ -3,15 +3,15 @@ namespace Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter; use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; -use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInPriceRangeFilter; -use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicator; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; +use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; use ONGR\ElasticsearchDSL\Search; /** * @author Arkadiusz Krakowiak */ -final class ProductInPriceRangeApplicator extends SearchCriteriaApplicator +final class ProductInPriceRangeApplicator implements SearchCriteriaApplicatorInterface { /** * @var QueryFactoryInterface @@ -29,16 +29,25 @@ public function __construct(QueryFactoryInterface $productInPriceRangeQueryFacto /** * {@inheritdoc} */ - public function applyProductInPriceRangeFilter(ProductInPriceRangeFilter $inPriceRangeFilter, Search $search) + public function apply(Criteria $criteria, Search $search) { $search->addPostFilter( - $this->productInPriceRangeQueryFactory->create([ - 'product_price_range' => [ - 'grater_than' => $inPriceRangeFilter->getGraterThan(), - 'less_than' => $inPriceRangeFilter->getLessThan() - ] - ]), + $this->productInPriceRangeQueryFactory->create($criteria->filtering()->fields()), BoolQuery::MUST ); } + + /** + * {@inheritdoc} + */ + public function supports(Criteria $criteria) + { + return + array_key_exists('product_price_range', $criteria->filtering()->fields()) && + array_key_exists('grater_than', $criteria->filtering()->fields()['product_price_range']) && + array_key_exists('less_than', $criteria->filtering()->fields()['product_price_range']) && + null != $criteria->filtering()->fields()['product_price_range']['grater_than'] && + null != $criteria->filtering()->fields()['product_price_range']['less_than'] + ; + } } diff --git a/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php b/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php index 315ec02..0f9c9cb 100644 --- a/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php +++ b/src/Search/Elastic/Applicator/Filter/ProductInTaxonApplicator.php @@ -3,15 +3,15 @@ namespace Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Filter; use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery; -use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductInTaxonFilter; -use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicator; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; +use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; use ONGR\ElasticsearchDSL\Search; /** * @author Arkadiusz Krakowiak */ -final class ProductInTaxonApplicator extends SearchCriteriaApplicator +final class ProductInTaxonApplicator implements SearchCriteriaApplicatorInterface { /** * @var QueryFactoryInterface @@ -29,8 +29,22 @@ public function __construct(QueryFactoryInterface $productInMainTaxonQueryFactor /** * {@inheritdoc} */ - public function applyProductInTaxonFilter(ProductInTaxonFilter $inTaxonFilter, Search $search) + public function apply(Criteria $criteria, Search $search) { - $search->addPostFilter($this->productInMainTaxonQueryFactory->create(['taxon_code' => $inTaxonFilter->getTaxonCode()]), BoolQuery::SHOULD); + $search->addPostFilter($this->productInMainTaxonQueryFactory->create( + $criteria->filtering()->fields()), + BoolQuery::SHOULD + ); + } + + /** + * {@inheritdoc} + */ + public function supports(Criteria $criteria) + { + return + array_key_exists('taxon_code', $criteria->filtering()->fields()) && + null != $criteria->filtering()->fields()['taxon_code'] + ; } } diff --git a/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php b/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php index 9bdb32f..f156977 100644 --- a/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php +++ b/src/Search/Elastic/Applicator/Query/MatchProductByNameApplicator.php @@ -2,50 +2,45 @@ namespace Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Query; -use Sylius\ElasticSearchPlugin\Search\Criteria\SearchPhrase; -use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicator; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; +use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Query\QueryFactoryInterface; use ONGR\ElasticsearchDSL\Search; /** * @author Arkadiusz Krakowiak */ -final class MatchProductByNameApplicator extends SearchCriteriaApplicator +final class MatchProductByNameApplicator implements SearchCriteriaApplicatorInterface { /** * @var QueryFactoryInterface */ private $matchProductNameQueryFactory; - /** - * @var QueryFactoryInterface - */ - private $emptyCriteriaQueryFactory; - /** * @param QueryFactoryInterface $matchProductNameQueryFactory - * @param QueryFactoryInterface $emptyCriteriaQueryFactory */ - public function __construct( - QueryFactoryInterface $matchProductNameQueryFactory, - QueryFactoryInterface $emptyCriteriaQueryFactory - ) { + public function __construct(QueryFactoryInterface $matchProductNameQueryFactory) + { $this->matchProductNameQueryFactory = $matchProductNameQueryFactory; - $this->emptyCriteriaQueryFactory = $emptyCriteriaQueryFactory; } /** * {@inheritdoc} */ - public function applySearchPhrase(SearchPhrase $searchPhrase, Search $search) + public function apply(Criteria $criteria, Search $search) { - if (null != $searchPhrase->getPhrase()) { - - $search->addQuery($this->matchProductNameQueryFactory->create(['phrase' => $searchPhrase->getPhrase()])); - - return; - } + $search->addQuery($this->matchProductNameQueryFactory->create($criteria->filtering()->fields())); + } - $search->addQuery($this->emptyCriteriaQueryFactory->create()); + /** + * {@inheritdoc} + */ + public function supports(Criteria $criteria) + { + return + array_key_exists('search', $criteria->filtering()->fields()) && + null != $criteria->filtering()->fields()['search'] + ; } } diff --git a/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php b/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php deleted file mode 100644 index ca507be..0000000 --- a/src/Search/Elastic/Applicator/SearchCriteriaApplicator.php +++ /dev/null @@ -1,52 +0,0 @@ - - */ -abstract class SearchCriteriaApplicator implements SearchCriteriaApplicatorInterface -{ - /** - * {@inheritDoc} - */ - public function apply($criteria, Search $search) - { - $method = $this->getApplyMethod($criteria); - - if (!method_exists($this, $method)) { - throw new \RuntimeException( - sprintf('Method "%s" does not exist for "%s".', $method, get_class($criteria)) - ); - } - - $this->$method($criteria, $search); - } - - /** - * @param mixed $criteria - * - * @return string - */ - private function getApplyMethod($criteria) - { - if (!is_object($criteria)) { - throw new \RuntimeException(sprintf('It should be query object, got "%s"', gettype($criteria))); - } - - $classParts = explode('\\', get_class($criteria)); - - return 'apply' . end($classParts); - } -} diff --git a/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php b/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php index 4e80dcd..e56c68f 100644 --- a/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php +++ b/src/Search/Elastic/Applicator/SearchCriteriaApplicatorInterface.php @@ -12,6 +12,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Elastic\Applicator; use ONGR\ElasticsearchDSL\Search; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; /** * @author Arkadiusz Krakowiak @@ -19,8 +20,15 @@ interface SearchCriteriaApplicatorInterface { /** - * @param mixed $criteria + * @param Criteria $criteria * @param Search $search */ - public function apply($criteria, Search $search); + public function apply(Criteria $criteria, Search $search); + + /** + * @param Criteria $criteria + * + * @return bool + */ + public function supports(Criteria $criteria); } diff --git a/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php b/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php index ca5d055..3c97f09 100644 --- a/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php +++ b/src/Search/Elastic/Applicator/Sort/SortByFieldApplicator.php @@ -2,15 +2,15 @@ namespace Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\Sort; -use Sylius\ElasticSearchPlugin\Search\Criteria\Ordering; -use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicator; +use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; +use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\Elastic\Factory\Sort\SortFactoryInterface; use ONGR\ElasticsearchDSL\Search; /** * @author Arkadiusz Krakowiak */ -final class SortByFieldApplicator extends SearchCriteriaApplicator +final class SortByFieldApplicator implements SearchCriteriaApplicatorInterface { /** * @var SortFactoryInterface @@ -28,8 +28,16 @@ public function __construct(SortFactoryInterface $sortByFieldQueryFactory) /** * {@inheritdoc} */ - public function applyOrdering(Ordering $ordering, Search $search) + public function apply(Criteria $criteria, Search $search) { - $search->addSort($this->sortByFieldQueryFactory->create($ordering)); + $search->addSort($this->sortByFieldQueryFactory->create($criteria->ordering())); + } + + /** + * {@inheritdoc} + */ + public function supports(Criteria $criteria) + { + return null != $criteria->ordering()->field() && null != $criteria->ordering()->direction(); } } diff --git a/src/Search/Elastic/ElasticSearchEngine.php b/src/Search/Elastic/ElasticSearchEngine.php index cc00cc0..72e49dd 100644 --- a/src/Search/Elastic/ElasticSearchEngine.php +++ b/src/Search/Elastic/ElasticSearchEngine.php @@ -3,6 +3,7 @@ namespace Sylius\ElasticSearchPlugin\Search\Elastic; use ONGR\ElasticsearchBundle\Service\Manager; +use Porpaginas\Arrays\ArrayResult; use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\Elastic\Applicator\SearchCriteriaApplicatorInterface; use Sylius\ElasticSearchPlugin\Search\SearchEngineInterface; @@ -22,11 +23,6 @@ final class ElasticSearchEngine implements SearchEngineInterface */ private $searchCriteriaApplicators = []; - /** - * @var SearchCriteriaApplicatorInterface - */ - private $sortingApplicator; - /** * @param Manager $manager * @param SearchCriteriaApplicatorInterface $sortingApplicator @@ -34,18 +30,14 @@ final class ElasticSearchEngine implements SearchEngineInterface public function __construct(Manager $manager, SearchCriteriaApplicatorInterface $sortingApplicator) { $this->manager = $manager; - $this->sortingApplicator = $sortingApplicator; } /** * @param SearchCriteriaApplicatorInterface $searchCriteriaApplicator - * @param string $criteriaClass */ - public function addSearchCriteriaApplicator( - SearchCriteriaApplicatorInterface $searchCriteriaApplicator, - $criteriaClass - ) { - $this->searchCriteriaApplicators[$criteriaClass] = $searchCriteriaApplicator; + public function addSearchCriteriaApplicator(SearchCriteriaApplicatorInterface $searchCriteriaApplicator) + { + $this->searchCriteriaApplicators[] = $searchCriteriaApplicator; } /** @@ -53,22 +45,15 @@ public function addSearchCriteriaApplicator( */ public function match(Criteria $criteria) { - $repository = $this->manager->getRepository($criteria->getResourceAlias()); + $repository = $this->manager->getRepository($criteria->documentClass()); $search = $repository->createSearch(); - - foreach ($criteria->getFiltering()->getFields() as $filter) { - if (!is_object($filter)) { - continue; - } - - if (isset($this->searchCriteriaApplicators[get_class($filter)])) { - $this->searchCriteriaApplicators[get_class($filter)]->apply($filter, $search); + foreach ($this->searchCriteriaApplicators as $searchCriteriaApplicator) { + if ($searchCriteriaApplicator->supports($criteria)) { + $searchCriteriaApplicator->apply($criteria, $search); } } - $this->sortingApplicator->applyOrdering($criteria->getOrdering(), $search); - - return $repository->findDocuments($search); + return new ArrayResult(iterator_to_array($repository->findArray($search))); } } diff --git a/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php b/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php index d52b9a9..7c26db4 100644 --- a/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php +++ b/src/Search/Elastic/Factory/Query/MatchProductNameQueryFactory.php @@ -16,10 +16,10 @@ final class MatchProductNameQueryFactory implements QueryFactoryInterface */ public function create(array $parameters = []) { - if (!isset($parameters['phrase']) || null == $parameters['phrase']) { + if (!isset($parameters['search']) || null == $parameters['search']) { throw new MissingQueryParameterException('search', get_class($this)); } - return new MatchQuery('name', $parameters['phrase']); + return new MatchQuery('name', $parameters['search']); } } diff --git a/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php b/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php index f2531d8..421a076 100644 --- a/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php +++ b/src/Search/Elastic/Factory/Sort/SortByFieldQueryFactory.php @@ -15,6 +15,6 @@ final class SortByFieldQueryFactory implements SortFactoryInterface */ public function create(Ordering $ordering) { - return new FieldSort($ordering->getField(), $ordering->getDirection()); + return new FieldSort($ordering->field(), $ordering->direction()); } } diff --git a/src/Search/SearchEngineInterface.php b/src/Search/SearchEngineInterface.php index ce0d20e..6dc7dbe 100644 --- a/src/Search/SearchEngineInterface.php +++ b/src/Search/SearchEngineInterface.php @@ -12,6 +12,7 @@ namespace Sylius\ElasticSearchPlugin\Search; use ONGR\ElasticsearchBundle\Result\DocumentIterator; +use Porpaginas\Result; use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; /** @@ -22,7 +23,7 @@ interface SearchEngineInterface /** * @param Criteria $criteria * - * @return DocumentIterator + * @return Result */ public function match(Criteria $criteria); } diff --git a/tests/Application/app/config/routing.yml b/tests/Application/app/config/routing.yml index 8344829..079afc3 100644 --- a/tests/Application/app/config/routing.yml +++ b/tests/Application/app/config/routing.yml @@ -17,5 +17,5 @@ sylius_api: prefix: /api sylius_search: - resource: "@LakionSyliusElasticSearchBundle/Resources/config/routing.yml" + resource: "@SyliusElasticSearchPlugin/Resources/config/routing.yml" prefix: / diff --git a/tests/Behat/Context/Domain/Shop/ProductContext.php b/tests/Behat/Context/Domain/Shop/ProductContext.php index 836872c..44d0178 100644 --- a/tests/Behat/Context/Domain/Shop/ProductContext.php +++ b/tests/Behat/Context/Domain/Shop/ProductContext.php @@ -13,6 +13,8 @@ use Behat\Behat\Context\Context; use ONGR\ElasticsearchBundle\Result\DocumentIterator; +use Porpaginas\Page; +use Porpaginas\Result; use Sylius\ElasticSearchPlugin\Document\Product; use Sylius\ElasticSearchPlugin\Search\Criteria\Criteria; use Sylius\ElasticSearchPlugin\Search\Criteria\Filtering\ProductHasOptionCodesFilter; @@ -46,49 +48,12 @@ public function __construct(SearchEngineInterface $searchEngine, SharedStorageIn $this->sharedStorage = $sharedStorage; } - /** - * @When I filter them by :mugTypeValue mug type - */ - public function iFilterThemByDoubleMugType($mugTypeValue) - { - $criteria = Criteria::fromQueryParameters(Product::class, [ - new ProductHasOptionCodesFilter([sprintf('mug_type_%s', $mugTypeValue)]), - ]); - - $this->match($criteria); - } - - /** - * @When I filter them by :mugTypeValue mug type or sticker size :stickerSizeValue - */ - public function iFilterThemByDoubleMugTypeAndStickerSize($mugTypeValue, $stickerSizeValue) - { - $criteria = Criteria::fromQueryParameters(Product::class, [ - new ProductHasOptionCodesFilter([sprintf('mug_type_%s', $mugTypeValue)]), - new ProductHasOptionCodesFilter([sprintf('sticker_size_%s', $stickerSizeValue)]), - ]); - - $this->match($criteria); - } - - /** - * @When I filter them by stickier size :stickerSizeValue - */ - public function iFilterThemByStickierSize($stickerSizeValue) - { - $criteria = Criteria::fromQueryParameters(Product::class, [ - new ProductHasOptionCodesFilter([sprintf('sticker_size_%s', $stickerSizeValue)]), - ]); - - $this->match($criteria); - } - /** * @When /^I filter them by price between ("[^"]+") and ("[^"]+")$/ */ public function iFilterThemByPriceBetweenAnd($graterThan, $lessThan) { - $criteria = Criteria::fromQueryParameters(Product::class, [new ProductInPriceRangeFilter($graterThan, $lessThan)]); + $criteria = Criteria::fromQueryParameters(Product::class, ['product_price_range' => ['grater_than' => $graterThan, 'less_than' => $lessThan]]); $this->match($criteria); } @@ -106,7 +71,7 @@ public function iViewTheListOfTheProductsWithoutFiltering() */ public function iFilterThemByChannel($channelCode) { - $criteria = Criteria::fromQueryParameters(Product::class, [new ProductInChannelFilter($channelCode)]); + $criteria = Criteria::fromQueryParameters(Product::class, ['channel_code' => $channelCode]); $this->match($criteria); } @@ -116,8 +81,8 @@ public function iFilterThemByChannel($channelCode) public function iFilterThemByChannelAndPriceBetweenAnd($channelCode, $graterThan, $lessThan) { $criteria = Criteria::fromQueryParameters(Product::class, [ - new ProductInChannelFilter($channelCode), - new ProductInPriceRangeFilter($graterThan, $lessThan), + 'channel_code' => $channelCode, + 'product_price_range' => ['grater_than' => $graterThan, 'less_than' => $lessThan], ]); $this->match($criteria); @@ -128,7 +93,7 @@ public function iFilterThemByChannelAndPriceBetweenAnd($channelCode, $graterThan */ public function iFilterThemByTaxon($taxonCode) { - $criteria = Criteria::fromQueryParameters(Product::class, [new ProductInTaxonFilter($taxonCode)]); + $criteria = Criteria::fromQueryParameters(Product::class, ['taxon_code' => $taxonCode]); $this->match($criteria); } @@ -150,7 +115,7 @@ public function iSortThemByNameInAscendingOrder($field, $order) */ public function iSearchForProductsWithName($name) { - $criteria = Criteria::fromQueryParameters(Product::class, [new SearchPhrase($name)]); + $criteria = Criteria::fromQueryParameters(Product::class, ['search' => $name]); $this->match($criteria); } @@ -159,7 +124,7 @@ public function iSearchForProductsWithName($name) */ public function iShouldSeeProductsOnTheList($numberOfProducts) { - /** @var DocumentIterator $result */ + /** @var Result $result */ $result = $this->sharedStorage->get('search_result'); Assert::eq($result->count(), $numberOfProducts); @@ -170,7 +135,7 @@ public function iShouldSeeProductsOnTheList($numberOfProducts) */ public function iShouldSeeProductsInOrderLike(...$productNames) { - /** @var DocumentIterator $searchResult */ + /** @var Result $searchResult */ $searchResult = $this->sharedStorage->get('search_result'); /** @@ -178,13 +143,13 @@ public function iShouldSeeProductsInOrderLike(...$productNames) * @var Product $product */ foreach ($searchResult as $position => $product) { - if ($product->getName() !== $productNames[$position]) { + if ($product['name'] !== $productNames[$position]) { throw new \RuntimeException( sprintf( 'Sorting failed at position "%s" expected value was "%s", but got "%s"', $position + 1, $productNames[$position], - $product->getName() + $product['name'] ) ); } @@ -199,12 +164,12 @@ public function iShouldSeeProductsInOrderLike(...$productNames) */ public function itShouldBe(...$expectedProductNames) { - /** @var DocumentIterator $searchResult */ + /** @var Result $searchResult */ $searchResult = $this->sharedStorage->get('search_result'); /** @var Product $product */ foreach ($searchResult as $product) { - Assert::oneOf($product->getName(), $expectedProductNames); + Assert::oneOf($product['name'], $expectedProductNames); } } diff --git a/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php b/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php index dd6ecb6..c165141 100644 --- a/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php +++ b/tests/DependencyInjection/Compiler/RegisterSearchCriteriaApplicatorPassTest.php @@ -31,7 +31,7 @@ public function it_collects_tagged_search_criteria_applicators() $this->setDefinition('sylius_elastic_search.search.elastic_engine', new Definition()); $this->setDefinition( 'sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes', - (new Definition(\stdClass::class))->addTag('search_criteria_applicator', ['applies' => 'productHasOption']) + (new Definition(\stdClass::class))->addTag('search_criteria_applicator') ); $this->compile(); @@ -40,8 +40,7 @@ public function it_collects_tagged_search_criteria_applicators() 'sylius_elastic_search.search.elastic_engine', 'addSearchCriteriaApplicator', [ - new Reference('sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes'), - 'productHasOption' + new Reference('sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes') ] ); } @@ -56,21 +55,6 @@ public function it_does_nothing_if_there_is_no_search_criteria_applicators() $this->assertContainerBuilderNotHasService('sylius_elastic_search.search.elastic_engine'); } - /** - * @test - */ - public function tagged_applicators_must_have_applies_attribute_configured() - { - $this->setDefinition('sylius_elastic_search.search.elastic_engine', new Definition()); - $this->setDefinition( - 'sylius_elastic_search.search_criteria_applicator.product_has_multiple_option_codes', - (new Definition(\stdClass::class))->addTag('search_criteria_applicator') - ); - - $this->expectException(\InvalidArgumentException::class); - $this->compile(); - } - /** * @test */