├── .docker ├── fpm.conf ├── nginx.conf ├── php.ini └── supervisord.conf ├── .github ├── CODEOWNERS └── workflows │ ├── build.yml │ └── coding_standard.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── UPGRADE-1.7.md ├── UPGRADE-3.2.0.md ├── UPGRADE-4.0.0.md ├── assets ├── admin │ ├── entry.js │ ├── js │ │ └── index.js │ └── scss │ │ └── main.scss └── shop │ ├── entry.js │ ├── entrypoint.js │ ├── js │ ├── elasticSearchAutocomplete.js │ ├── elasticSearchCheckboxChangeSubmit.js │ ├── index.js │ ├── initAutocomplete.js │ └── initCheckboxChangeSubmit.js │ └── scss │ ├── elasticSearchAutocomplete.scss │ └── main.scss ├── behat.yml.dist ├── bin └── create_node_symlink.php ├── composer.json ├── config ├── api_platform │ └── resources │ │ └── Product.xml ├── config.yml ├── indexes │ ├── bitbag_attribute_taxons.yml │ ├── bitbag_option_taxons.yml │ ├── bitbag_shop_facets.yml │ └── bitbag_shop_products.yml ├── routing.yml ├── services.xml ├── services │ ├── api │ │ ├── data_provider.xml │ │ ├── request_data_handler.xml │ │ └── resolver.xml │ ├── context.xml │ ├── controller.xml │ ├── controller │ │ ├── api.xml │ │ └── shop.xml │ ├── event_listener.xml │ ├── facet.xml │ ├── finder.xml │ ├── form.xml │ ├── property_builder.xml │ ├── property_name_resolver.xml │ ├── query_builder.xml │ ├── transformer.xml │ └── twig.xml └── twig │ └── bitbag_twig_hooks.yml ├── doc ├── es_browser.png ├── es_results.png ├── functionalities.md ├── installation.md ├── installation │ ├── attribute-mapping.md │ └── xml-mapping.md ├── search_results.png ├── searchbar.png ├── taxon_filters.png └── taxon_searchbar.png ├── docker-compose.yml ├── easy-coding-standard.yml ├── ecs.php ├── etc └── build │ ├── .gitignore │ └── .gitkeep ├── features └── shop │ ├── searching_products_by_a_partial_name.feature │ ├── site_wide_searching_products.feature │ └── site_wide_searching_products_113.feature ├── node_modules ├── package.json ├── phpspec.yml.dist ├── phpstan.neon ├── phpunit.xml ├── spec ├── Context │ ├── ProductAttributesContextSpec.php │ ├── ProductOptionsContextSpec.php │ ├── ProductProductAttributesContextSpec.php │ └── TaxonContextSpec.php ├── Controller │ ├── Action │ │ └── Shop │ │ │ └── TaxonProductsSearchActionSpec.php │ ├── RequestDataHandler │ │ ├── PaginationDataHandlerSpec.php │ │ ├── ShopProductListDataHandlerSpec.php │ │ └── ShopProductsSortDataHandlerSpec.php │ └── Response │ │ ├── DTO │ │ └── ItemSpec.php │ │ └── ItemsResponseSpec.php ├── Exception │ └── TaxonNotFoundExceptionSpec.php ├── Facet │ ├── AttributeFacetSpec.php │ ├── OptionFacetSpec.php │ ├── PriceFacetSpec.php │ └── TaxonFacetSpec.php ├── Finder │ ├── NamedProductsFinderSpec.php │ ├── ProductAttributesFinderSpec.php │ ├── ProductOptionsFinderSpec.php │ └── ShopProductsFinderSpec.php ├── Formatter │ └── StringFormatterSpec.php ├── PropertyBuilder │ ├── AttributeBuilderSpec.php │ ├── AttributeTaxonsBuilderSpec.php │ ├── ChannelPricingBuilderSpec.php │ ├── ChannelsBuilderSpec.php │ ├── Mapper │ │ └── ProductTaxonsMapperSpec.php │ ├── OptionBuilderSpec.php │ ├── OptionTaxonsBuilderSpec.php │ ├── ProductCreatedAtPropertyBuilderSpec.php │ ├── ProductDescriptionBuilderSpec.php │ ├── ProductNameBuilderSpec.php │ ├── ProductShortDescriptionBuilderSpec.php │ ├── ProductTaxonsBuilderSpec.php │ └── SoldUnitsPropertyBuilderSpec.php ├── PropertyNameResolver │ ├── ConcatedNameResolverSpec.php │ └── PriceNameResolverSpec.php ├── QueryBuilder │ ├── ContainsNameQueryBuilderSpec.php │ ├── HasAttributesQueryBuilderSpec.php │ ├── HasChannelQueryBuilderSpec.php │ ├── HasOptionsQueryBuilderSpec.php │ ├── HasPriceBetweenQueryBuilderSpec.php │ ├── HasTaxonQueryBuilderSpec.php │ ├── IsEnabledQueryBuilderSpec.php │ ├── ProductAttributesByTaxonQueryBuilderSpec.php │ ├── ProductOptionsByTaxonQueryBuilderSpec.php │ ├── ProductsByPartialNameQueryBuilderSpec.php │ ├── SiteWideProductsQueryBuilderSpec.php │ └── TaxonProductsQueryBuilderSpec.php ├── Transformer │ └── Product │ │ ├── ChannelPricingTransformerSpec.php │ │ ├── ImageTransformerSpec.php │ │ └── SlugTransformerSpec.php └── Twig │ └── Extension │ └── UnsetArrayElementsExtensionSpec.php ├── src ├── Api │ ├── DataProvider │ │ └── ProductCollectionDataProvider.php │ ├── OpenApi │ │ └── Documentation │ │ │ └── ProductSearchDocumentationModifier.php │ ├── RequestDataHandler │ │ ├── RequestDataHandler.php │ │ └── RequestDataHandlerInterface.php │ └── Resolver │ │ ├── FacetsResolver.php │ │ └── FacetsResolverInterface.php ├── BitBagSyliusElasticsearchPlugin.php ├── CompilerPass │ └── AuthenticationManagerPolyfillPass.php ├── Context │ ├── ProductAttributesContext.php │ ├── ProductAttributesContextInterface.php │ ├── ProductOptionsContext.php │ ├── ProductOptionsContextInterface.php │ ├── ProductProductAttributesContext.php │ ├── TaxonContext.php │ └── TaxonContextInterface.php ├── Controller │ ├── Action │ │ ├── Api │ │ │ └── ListProductsByPartialNameAction.php │ │ └── Shop │ │ │ ├── AbstractSearchAction.php │ │ │ ├── SiteWideProductsSearchAction.php │ │ │ └── TaxonProductsSearchAction.php │ ├── RequestDataHandler │ │ ├── DataHandlerInterface.php │ │ ├── PaginationDataHandler.php │ │ ├── PaginationDataHandlerInterface.php │ │ ├── ShopProductListDataHandler.php │ │ ├── ShopProductsSortDataHandler.php │ │ ├── SiteWideDataHandler.php │ │ ├── SortDataHandlerInterface.php │ │ └── TaxonDataHandler.php │ └── Response │ │ ├── DTO │ │ └── Item.php │ │ └── ItemsResponse.php ├── DependencyInjection │ └── BitBagSyliusElasticsearchExtension.php ├── EventListener │ ├── OrderProductsListener.php │ ├── ProductTaxonIndexListener.php │ ├── ResourceIndexListener.php │ └── ResourceIndexListenerInterface.php ├── Exception │ └── TaxonNotFoundException.php ├── Facet │ ├── AttributeFacet.php │ ├── AutoDiscoverRegistry.php │ ├── AutoDiscoverRegistryInterface.php │ ├── FacetInterface.php │ ├── FacetNotFoundException.php │ ├── OptionFacet.php │ ├── PriceFacet.php │ ├── Registry.php │ ├── RegistryInterface.php │ └── TaxonFacet.php ├── Finder │ ├── NamedProductsFinder.php │ ├── NamedProductsFinderInterface.php │ ├── ProductAttributesFinder.php │ ├── ProductAttributesFinderInterface.php │ ├── ProductOptionsFinder.php │ ├── ProductOptionsFinderInterface.php │ ├── ShopProductsFinder.php │ └── ShopProductsFinderInterface.php ├── Form │ ├── EventSubscriber │ │ └── AddFacetsEventSubscriber.php │ ├── Resolver │ │ ├── FacetsResolver.php │ │ ├── ProductsFilterFacetResolver.php │ │ └── ProductsFilterFacetResolverInterface.php │ └── Type │ │ ├── AbstractFilterType.php │ │ ├── ChoiceMapper │ │ ├── AttributesMapper │ │ │ ├── AttributesMapperCollectorInterface.php │ │ │ ├── AttributesTypeDateMapper.php │ │ │ ├── AttributesTypeDateTimeMapper.php │ │ │ └── AttributesTypePercentMapper.php │ │ ├── ProductAttributesMapper.php │ │ ├── ProductAttributesMapperInterface.php │ │ ├── ProductOptionsMapper.php │ │ └── ProductOptionsMapperInterface.php │ │ ├── NameFilterType.php │ │ ├── PriceFilterType.php │ │ ├── ProductAttributesFilterType.php │ │ ├── ProductOptionsFilterType.php │ │ ├── SearchFacetsType.php │ │ ├── SearchType.php │ │ └── ShopProductsFilterType.php ├── Formatter │ ├── StringFormatter.php │ └── StringFormatterInterface.php ├── Model │ ├── ProductVariantInterface.php │ ├── ProductVariantTrait.php │ ├── Search.php │ ├── SearchBox.php │ └── SearchFacets.php ├── PropertyBuilder │ ├── AbstractBuilder.php │ ├── AttributeBuilder.php │ ├── AttributeTaxonsBuilder.php │ ├── ChannelPricingBuilder.php │ ├── ChannelsBuilder.php │ ├── Mapper │ │ ├── ProductTaxonsMapper.php │ │ └── ProductTaxonsMapperInterface.php │ ├── OptionBuilder.php │ ├── OptionTaxonsBuilder.php │ ├── ProductCodeBuilder.php │ ├── ProductCreatedAtPropertyBuilder.php │ ├── ProductDescriptionBuilder.php │ ├── ProductNameBuilder.php │ ├── ProductShortDescriptionBuilder.php │ ├── ProductTaxonPositionPropertyBuilder.php │ ├── ProductTaxonsBuilder.php │ ├── PropertyBuilderInterface.php │ └── SoldUnitsPropertyBuilder.php ├── PropertyNameResolver │ ├── ConcatedNameResolver.php │ ├── ConcatedNameResolverInterface.php │ ├── PriceNameResolver.php │ ├── PriceNameResolverInterface.php │ ├── SearchPropertyNameResolverRegistry.php │ └── SearchPropertyNameResolverRegistryInterface.php ├── QueryBuilder │ ├── AttributesQueryBuilder │ │ ├── AttributesQueryBuilderCollectorInterface.php │ │ ├── AttributesTypeDateQueryBuilder.php │ │ ├── AttributesTypeNumberQueryBuilder.php │ │ └── AttributesTypeTextQueryBuilder.php │ ├── ContainsNameQueryBuilder.php │ ├── FormQueryBuilder │ │ ├── SiteWideFacetsQueryBuilder.php │ │ ├── SiteWideFacetsQueryBuilderInterface.php │ │ ├── TaxonFacetsQueryBuilder.php │ │ └── TaxonFacetsQueryBuilderInterface.php │ ├── HasAttributesQueryBuilder.php │ ├── HasChannelQueryBuilder.php │ ├── HasOptionsQueryBuilder.php │ ├── HasPriceBetweenQueryBuilder.php │ ├── HasTaxonQueryBuilder.php │ ├── IsEnabledQueryBuilder.php │ ├── ProductAttributesByTaxonQueryBuilder.php │ ├── ProductOptionsByTaxonQueryBuilder.php │ ├── ProductsByPartialNameQueryBuilder.php │ ├── QueryBuilderInterface.php │ ├── SiteWideProductsQueryBuilder.php │ └── TaxonProductsQueryBuilder.php ├── Refresher │ ├── ResourceRefresher.php │ └── ResourceRefresherInterface.php ├── Repository │ ├── OrderItemRepository.php │ ├── OrderItemRepositoryInterface.php │ ├── ProductAttributeRepository.php │ ├── ProductAttributeRepositoryInterface.php │ ├── ProductAttributeValueRepository.php │ ├── ProductAttributeValueRepositoryInterface.php │ ├── ProductOptionRepository.php │ ├── ProductOptionRepositoryInterface.php │ ├── ProductVariantRepository.php │ ├── ProductVariantRepositoryInterface.php │ ├── TaxonRepository.php │ └── TaxonRepositoryInterface.php ├── Transformer │ └── Product │ │ ├── ChannelPricingTransformer.php │ │ ├── ImageTransformer.php │ │ ├── SlugTransformer.php │ │ └── TransformerInterface.php └── Twig │ ├── Component │ └── SearchFormComponent.php │ └── Extension │ └── UnsetArrayElementsExtension.php ├── templates └── Shop │ ├── Layout │ └── Header │ │ └── searchForm.html.twig │ ├── SearchForm │ └── searchForm.html.twig │ ├── SiteWideSearch │ ├── content │ │ ├── body.html.twig │ │ ├── body │ │ │ ├── main │ │ │ │ ├── limit │ │ │ │ │ ├── menu.html.twig │ │ │ │ │ └── toggle.html.twig │ │ │ │ ├── pagination.html.twig │ │ │ │ ├── products.html.twig │ │ │ │ ├── search.html.twig │ │ │ │ ├── sorting.html.twig │ │ │ │ └── sorting │ │ │ │ │ └── item.html.twig │ │ │ └── sidebar │ │ │ │ └── facets.html.twig │ │ └── breadcrumbs.html.twig │ └── index.html.twig │ └── TaxonProductsSearch │ ├── content │ ├── body.html.twig │ ├── body │ │ ├── main │ │ │ ├── limit │ │ │ │ ├── menu.html.twig │ │ │ │ └── toggle.html.twig │ │ │ ├── pagination.html.twig │ │ │ ├── products.html.twig │ │ │ ├── search.html.twig │ │ │ ├── sorting.html.twig │ │ │ └── sorting │ │ │ │ └── item.html.twig │ │ └── sidebar │ │ │ └── facets.html.twig │ └── breadcrumbs.html.twig │ └── index.html.twig ├── tests ├── Application │ ├── .babelrc │ ├── .env │ ├── .env.test │ ├── .eslintrc.js │ ├── .github │ │ ├── CODEOWNERS │ │ └── workflows │ │ │ └── build.yml │ ├── .gitignore │ ├── Kernel.php │ ├── assets │ │ ├── admin │ │ │ └── entrypoint.js │ │ ├── controllers.json │ │ └── shop │ │ │ ├── app.js │ │ │ ├── controllers.json │ │ │ ├── controllers │ │ │ └── .gitignore │ │ │ └── entrypoint.js │ ├── bin │ │ └── console │ ├── composer.json │ ├── composer.lock │ ├── config │ │ ├── api_platform │ │ │ └── .gitkeep │ │ ├── bootstrap.php │ │ ├── bundles.php │ │ ├── jwt │ │ │ ├── private.pem │ │ │ └── public.pem │ │ ├── packages │ │ │ ├── _sylius.yaml │ │ │ ├── assets.yaml │ │ │ ├── bitbag_sylius_elasticsearch_plugin.yaml │ │ │ ├── dev │ │ │ │ ├── framework.yaml │ │ │ │ ├── monolog.yaml │ │ │ │ ├── nelmio_alice.yaml │ │ │ │ ├── routing.yaml │ │ │ │ └── web_profiler.yaml │ │ │ ├── doctrine.yaml │ │ │ ├── doctrine_migrations.yaml │ │ │ ├── fos_elastica.yaml │ │ │ ├── framework.yaml │ │ │ ├── http_discovery.yaml │ │ │ ├── lexik_jwt_authentication.yaml │ │ │ ├── liip_imagine.yaml │ │ │ ├── mailer.yaml │ │ │ ├── prod │ │ │ │ ├── doctrine.yaml │ │ │ │ └── monolog.yaml │ │ │ ├── routing.yaml │ │ │ ├── security.yaml │ │ │ ├── staging │ │ │ │ └── monolog.yaml │ │ │ ├── stof_doctrine_extensions.yaml │ │ │ ├── test │ │ │ │ ├── fidry_alice_data_fixtures.yaml │ │ │ │ ├── framework.yaml │ │ │ │ ├── mailer.yaml │ │ │ │ ├── monolog.yaml │ │ │ │ ├── nelmio_alice.yaml │ │ │ │ ├── security.yaml │ │ │ │ ├── sylius_theme.yaml │ │ │ │ ├── sylius_uploader.yaml │ │ │ │ └── web_profiler.yaml │ │ │ ├── test_cached │ │ │ │ ├── doctrine.yaml │ │ │ │ ├── fidry_alice_data_fixtures.yaml │ │ │ │ ├── framework.yaml │ │ │ │ ├── mailer.yaml │ │ │ │ ├── monolog.yaml │ │ │ │ ├── security.yaml │ │ │ │ ├── sylius_channel.yaml │ │ │ │ ├── sylius_theme.yaml │ │ │ │ ├── sylius_uploader.yaml │ │ │ │ └── twig.yaml │ │ │ ├── translation.yaml │ │ │ ├── twig.yaml │ │ │ ├── twig_extensions.yaml │ │ │ └── webpack_encore.yaml │ │ ├── routes.yaml │ │ ├── routes │ │ │ ├── api_platform.yaml │ │ │ ├── bitbag_sylius_elasticsearch_plugin.yaml │ │ │ ├── dev │ │ │ │ ├── twig.yaml │ │ │ │ └── web_profiler.yaml │ │ │ ├── liip_imagine.yaml │ │ │ ├── sylius_admin.yaml │ │ │ ├── sylius_api.yaml │ │ │ ├── sylius_shop.yaml │ │ │ ├── test │ │ │ │ ├── routing.yaml │ │ │ │ └── sylius_test_plugin.yaml │ │ │ └── test_cached │ │ │ │ ├── routing.yaml │ │ │ │ └── sylius_test_plugin.yaml │ │ ├── services.yaml │ │ ├── services_test.yaml │ │ ├── services_test_cached.yaml │ │ └── symfony │ │ │ └── 4.4 │ │ │ └── packages │ │ │ └── framework.yaml │ ├── gulpfile.babel.js.temp │ ├── package.json │ ├── public │ │ ├── .htaccess │ │ ├── favicon.ico │ │ ├── index.php │ │ └── robots.txt │ ├── templates │ │ ├── .gitignore │ │ └── shop │ │ │ ├── javascripts.html.twig │ │ │ └── stylesheets.html.twig │ ├── translations │ │ └── .gitignore │ └── webpack.config.js ├── Behat │ ├── Context │ │ ├── Api │ │ │ └── Shop │ │ │ │ └── ProductContext.php │ │ ├── Setup │ │ │ ├── ElasticsearchContext.php │ │ │ ├── ProductAttributeContext.php │ │ │ ├── ProductContext.php │ │ │ └── ProductTaxonContext.php │ │ └── Ui │ │ │ └── Shop │ │ │ ├── HomepageContext.php │ │ │ ├── ProductContext.php │ │ │ └── SearchContext.php │ ├── Page │ │ └── Shop │ │ │ ├── HomePage.php │ │ │ ├── HomePageInterface.php │ │ │ ├── Product │ │ │ ├── IndexPage.php │ │ │ └── IndexPageInterface.php │ │ │ ├── SearchPage.php │ │ │ └── SearchPageInterface.php │ ├── Resources │ │ ├── services.xml │ │ ├── services │ │ │ ├── contexts │ │ │ │ ├── api.xml │ │ │ │ ├── setup.xml │ │ │ │ └── ui.xml │ │ │ └── pages │ │ │ │ └── shop │ │ │ │ ├── home_page.xml │ │ │ │ ├── product.xml │ │ │ │ └── search.xml │ │ ├── suites.yml │ │ └── suites │ │ │ ├── api │ │ │ └── searching_products.yaml │ │ │ └── ui │ │ │ ├── filtering_products.yaml │ │ │ └── site_wide_searching_products.yaml │ └── Service │ │ └── Populate.php └── PHPUnit │ └── Integration │ ├── Api │ ├── DataFixtures │ │ └── ORM │ │ │ ├── test_it_finds_products_by_name.yaml │ │ │ ├── test_it_finds_products_by_name_and_facets.yaml │ │ │ ├── test_it_finds_products_by_name_and_multiple_facets.yaml │ │ │ └── test_it_updates_facets.yaml │ ├── ProductListingTest.php │ └── Responses │ │ └── Expected │ │ ├── test_it_finds_products_by_name.json │ │ ├── test_it_finds_products_by_name_and_facets.json │ │ ├── test_it_finds_products_by_name_and_multiple_facets.json │ │ └── test_it_updates_facets.json │ ├── DataFixtures │ └── ORM │ │ ├── Repository │ │ └── ProductAttributeValueRepositoryTest │ │ │ ├── test_product_attribute_repository.yaml │ │ │ ├── test_product_attribute_value_repository.yaml │ │ │ └── test_product_attribute_value_repository_for_ancestor_taxon.yaml │ │ └── Type │ │ └── ChoiceMapper │ │ └── AttributesMapper │ │ ├── test_attributes_type_date_mapper.yaml │ │ ├── test_attributes_type_date_time_mapper.yaml │ │ └── test_attributes_type_percent_mapper.yaml │ ├── Form │ └── Type │ │ └── ChoiceMapper │ │ └── AttributesMapper │ │ ├── AttributesTypeDateMapperTest.php │ │ ├── AttributesTypeDateTimeMapperTest.php │ │ └── AttributesTypePercentMapperTest.php │ ├── IntegrationTestCase.php │ └── Repository │ ├── ProductAttributeRepositoryTest.php │ └── ProductAttributeValueRepositoryTest.php ├── translations ├── messages.ar.yml ├── messages.cs.yml ├── messages.en.yml ├── messages.fr.yml ├── messages.nl.yml └── validators.en.yml ├── webpack.config.js └── yarn.lock /.docker/fpm.conf: -------------------------------------------------------------------------------- 1 | [www] 2 | user = www-data 3 | group = www-data 4 | 5 | listen = /var/run/php-www.sock 6 | listen.owner = www-data 7 | listen.group = www-data 8 | listen.mode = 0660 9 | 10 | clear_env = no 11 | 12 | pm = dynamic 13 | pm.max_children = 5 14 | pm.start_servers = 2 15 | pm.min_spare_servers = 1 16 | pm.max_spare_servers = 3 17 | 18 | pm.status_path = /status 19 | catch_workers_output = yes 20 | 21 | security.limit_extensions = .php 22 | -------------------------------------------------------------------------------- /.docker/nginx.conf: -------------------------------------------------------------------------------- 1 | user www-data; 2 | worker_processes auto; 3 | daemon off; 4 | pid /run/nginx.pid; 5 | 6 | include /etc/nginx/modules-enabled/*.conf; 7 | 8 | events { 9 | worker_connections 1024; 10 | } 11 | 12 | http { 13 | include /etc/nginx/mime.types; 14 | default_type application/octet-stream; 15 | 16 | server_tokens off; 17 | 18 | client_max_body_size 64m; 19 | sendfile on; 20 | tcp_nodelay on; 21 | tcp_nopush on; 22 | 23 | gzip_vary on; 24 | 25 | access_log /var/log/nginx/access.log; 26 | error_log /var/log/nginx/error.log; 27 | 28 | server { 29 | listen 80; 30 | 31 | root /app/tests/Application/public; 32 | index index.php; 33 | 34 | location / { 35 | try_files $uri /index.php$is_args$args; 36 | } 37 | 38 | location ~ \.php$ { 39 | include fastcgi_params; 40 | 41 | fastcgi_pass unix:/var/run/php-www.sock; 42 | fastcgi_split_path_info ^(.+\.php)(/.*)$; 43 | 44 | fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; 45 | fastcgi_param DOCUMENT_ROOT $realpath_root; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /.docker/php.ini: -------------------------------------------------------------------------------- 1 | [PHP] 2 | memory_limit=512M 3 | 4 | [date] 5 | date.timezone=${PHP_DATE_TIMEZONE} 6 | 7 | [opcache] 8 | opcache.enable=0 9 | opcache.memory_consumption=256 10 | opcache.max_accelerated_files=20000 11 | opcache.validate_timestamps=0 12 | ;opcache.preload=/app/config/preload.php 13 | opcache.preload_user=www-data 14 | opcache.jit=1255 15 | opcache.jit_buffer_size=256M 16 | -------------------------------------------------------------------------------- /.docker/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon = true 3 | user = root 4 | pidfile = /run/supervisord.pid 5 | 6 | [program:nginx] 7 | command = /usr/sbin/nginx 8 | user = root 9 | autostart = true 10 | 11 | [program:php-fpm] 12 | command = /usr/sbin/php-fpm -F 13 | user = root 14 | autostart = true 15 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | @ @BitBagCommerce 2 | * @Sylius/core-team 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | /node_modules/ 3 | /composer.lock 4 | 5 | /etc/build/* 6 | !/etc/build/.gitignore 7 | 8 | /tests/Application/yarn.lock 9 | 10 | /behat.yml 11 | /phpspec.yml 12 | 13 | /vendor/ 14 | /node_modules/ 15 | package-lock.json 16 | 17 | /etc/build/* 18 | !/etc/build/.gitignore 19 | 20 | tests/Application/node_modules/ 21 | 22 | tests/Application/var/ 23 | !tests/Application/var/.gitkeep 24 | 25 | tests/Application/web/* 26 | !tests/Application/web/favicon.ico 27 | !tests/Application/web/app.php 28 | !tests/Application/web/app_dev.php 29 | !tests/Application/web/app_test.php 30 | 31 | /tests/Application/yarn.lock 32 | 33 | /composer.lock 34 | 35 | /etc/build/* 36 | !/etc/build/.gitkeep -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016-2019 Mikołaj Król 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /UPGRADE-3.2.0.md: -------------------------------------------------------------------------------- 1 | # UPGRADE FROM 3.2.0 TO 3.2.1 2 | 3 | #### Changes regarding to product attributes: 4 | 5 | * Support for date and datetime attributes has been added to `BitBag\SyliusElasticsearchPlugin\PropertyBuilder\AttributeBuilder`. After the changes, date and datetime type attributes are stored in elasticsearch in the default format: date type = `Y-m-d` and datetime type = `Y-m-d H:i:s` or the format that was set in the attribute configuration in the `format` field. If in a project using this plugin you had your own implementation of the filter for date and/or datetime type attributes then you must follow the new format. 6 | * After uploading the new version, you will have to restart the data population process with the `reset` option enabled (means simply `bin/console fos:elastic:populate`) because you have to reset the mapping beforehand in order for this field to be saved in the new format. 7 | 8 | 9 | -------------------------------------------------------------------------------- /UPGRADE-4.0.0.md: -------------------------------------------------------------------------------- 1 | # UPGRADE FROM 3.* TO 4.0.0 2 | 3 | #### Changes related to facets: 4 | 5 | Since version 4 standard filters are deprecated, and replaced by facets. Facets are a more flexible and powerful way to filter products in the search engine. The main difference is that facets are not limited to the predefined values of the attribute, but they are generated based on the values of the products in the index. This means that the user can filter products by any value of the attribute, not only the predefined ones. 6 | 7 | If you still want to use the old filters, you have to manually add them in form extension - they are still in the code: `BitBag\SyliusElasticsearchPlugin\Form\Type\ProductAttributesFilterType` and `BitBag\SyliusElasticsearchPlugin\Form\Type\ProductOptionsFilterType`. 8 | -------------------------------------------------------------------------------- /assets/admin/entry.js: -------------------------------------------------------------------------------- 1 | import './scss/main.scss' 2 | import './js' 3 | -------------------------------------------------------------------------------- /assets/admin/js/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/assets/admin/js/index.js -------------------------------------------------------------------------------- /assets/admin/scss/main.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/assets/admin/scss/main.scss -------------------------------------------------------------------------------- /assets/shop/entry.js: -------------------------------------------------------------------------------- 1 | import './scss/main.scss' 2 | import './js' 3 | -------------------------------------------------------------------------------- /assets/shop/entrypoint.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/assets/shop/entrypoint.js -------------------------------------------------------------------------------- /assets/shop/js/elasticSearchCheckboxChangeSubmit.js: -------------------------------------------------------------------------------- 1 | export default class ElasticSearchCheckboxChangeSubmit { 2 | constructor(config = {}) { 3 | this.config = config; 4 | this.defaultConfig = { 5 | checkboxSelector: '.bitbag-sylius-elasticsearch-plugin-facets-form input[type="checkbox"]', 6 | formSelector: 'form', 7 | }; 8 | this.finalConfig = {...this.defaultConfig, ...config}; 9 | } 10 | 11 | init() { 12 | const checkboxes = document.querySelectorAll(this.finalConfig.checkboxSelector); 13 | checkboxes.forEach((checkbox) => { 14 | checkbox.addEventListener('change', () => { 15 | this._submitForm(checkbox); 16 | }); 17 | }); 18 | } 19 | 20 | _submitForm(checkbox) { 21 | const form = checkbox.closest(this.finalConfig.formSelector); 22 | if (form) { 23 | form.submit(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /assets/shop/js/index.js: -------------------------------------------------------------------------------- 1 | import './initAutocomplete'; 2 | import './initCheckboxChangeSubmit'; 3 | -------------------------------------------------------------------------------- /assets/shop/js/initAutocomplete.js: -------------------------------------------------------------------------------- 1 | import ElasticSearchAutocomplete from './elasticSearchAutocomplete'; 2 | 3 | new ElasticSearchAutocomplete().init(); 4 | -------------------------------------------------------------------------------- /assets/shop/js/initCheckboxChangeSubmit.js: -------------------------------------------------------------------------------- 1 | import ElasticSearchCheckboxChangeSubmit from './elasticSearchCheckboxChangeSubmit'; 2 | 3 | document.addEventListener('DOMContentLoaded', () => { 4 | new ElasticSearchCheckboxChangeSubmit().init(); 5 | }); 6 | -------------------------------------------------------------------------------- /assets/shop/scss/main.scss: -------------------------------------------------------------------------------- 1 | @import 'elasticSearchAutocomplete'; 2 | 3 | -------------------------------------------------------------------------------- /config/api_platform/resources/Product.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | shop:product:index 19 | sylius:shop:product:index 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /config/config.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: "indexes/bitbag_shop_products.yml" } 3 | - { resource: "indexes/bitbag_option_taxons.yml" } 4 | - { resource: "indexes/bitbag_attribute_taxons.yml" } 5 | - { resource: "indexes/bitbag_shop_facets.yml" } 6 | - { resource: "twig/bitbag_twig_hooks.yml" } 7 | 8 | parameters: 9 | env(BITBAG_ES_INDEX_PREFIX): "" 10 | env(BITBAG_ES_HOST): "localhost" 11 | env(BITBAG_ES_PORT): "9200" 12 | bitbag_es_index_prefix: "%env(BITBAG_ES_INDEX_PREFIX)%" 13 | bitbag_es_host: "%env(BITBAG_ES_HOST)%" 14 | bitbag_es_port: "%env(BITBAG_ES_PORT)%" 15 | 16 | bitbag_es_pagination_available_page_limits: [9, 18, 36] 17 | bitbag_es_pagination_default_limit: 9 18 | bitbag_es_fuzziness: AUTO 19 | bitbag_es_facets_auto_discover: true 20 | bitbag_es_excluded_facet_attributes: [] 21 | bitbag_es_excluded_facet_options: [] 22 | 23 | fos_elastica: 24 | clients: 25 | default: 26 | host: "%bitbag_es_host%" 27 | port: "%bitbag_es_port%" 28 | 29 | twig: 30 | globals: 31 | bitbag_es_pagination_available_page_limits: "%bitbag_es_pagination_available_page_limits%" 32 | -------------------------------------------------------------------------------- /config/indexes/bitbag_attribute_taxons.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | bitbag_es_shop_attribute_taxons_property: attribute_taxons 3 | 4 | fos_elastica: 5 | indexes: 6 | bitbag_attribute_taxons: 7 | index_name: "%bitbag_es_index_prefix%bitbag_attribute_taxons_%kernel.environment%" 8 | properties: 9 | attribute_code: 10 | property_path: code 11 | persistence: 12 | driver: orm 13 | model: "%sylius.model.product_attribute.class%" 14 | listener: 15 | defer: false 16 | logger: true 17 | elastica_to_model_transformer: 18 | ignore_missing: true 19 | -------------------------------------------------------------------------------- /config/indexes/bitbag_option_taxons.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | bitbag_es_shop_option_taxons_property: option_taxons 3 | 4 | fos_elastica: 5 | indexes: 6 | bitbag_option_taxons: 7 | index_name: "%bitbag_es_index_prefix%bitbag_option_taxons_%kernel.environment%" 8 | properties: 9 | option_code: 10 | property_path: code 11 | persistence: 12 | driver: orm 13 | model: "%sylius.model.product_option.class%" 14 | listener: 15 | defer: false 16 | logger: true 17 | elastica_to_model_transformer: 18 | ignore_missing: true 19 | -------------------------------------------------------------------------------- /config/indexes/bitbag_shop_facets.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | bitbag_es_shop_price_facet_interval: 5000 3 | -------------------------------------------------------------------------------- /config/indexes/bitbag_shop_products.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | bitbag_es_shop_channels_property: channels 3 | bitbag_es_shop_enabled_property: enabled 4 | bitbag_es_shop_product_taxons_property: product_taxons 5 | bitbag_es_shop_product_sold_units: sold_units 6 | bitbag_es_shop_product_created_at: product_created_at 7 | bitbag_es_shop_name_property_prefix: name 8 | bitbag_es_shop_product_price_property_prefix: price 9 | bitbag_es_shop_option_property_prefix: option 10 | bitbag_es_shop_attribute_property_prefix: attribute 11 | bitbag_es_shop_description_property_prefix: description 12 | bitbag_es_shop_short_description_property_prefix: short_description 13 | bitbag_es_shop_taxon_position_property_prefix: taxon_position 14 | 15 | fos_elastica: 16 | indexes: 17 | bitbag_shop_product: 18 | index_name: "%bitbag_es_index_prefix%bitbag_shop_products_%kernel.environment%" 19 | properties: 20 | enabled: ~ 21 | persistence: 22 | driver: orm 23 | model: "%sylius.model.product.class%" 24 | listener: 25 | defer: false 26 | logger: true 27 | elastica_to_model_transformer: 28 | ignore_missing: true 29 | -------------------------------------------------------------------------------- /config/routing.yml: -------------------------------------------------------------------------------- 1 | bitbag_sylius_elasticsearch_plugin_shop_taxon_products: 2 | path: /{_locale}/taxons/{slug} 3 | defaults: 4 | _controller: bitbag_sylius_elasticsearch_plugin.controller.action.shop.taxon_products_search 5 | template: "@BitBagSyliusElasticsearchPlugin/Shop/TaxonProductsSearch/index.html.twig" 6 | requirements: 7 | slug: .+ 8 | 9 | bitbag_sylius_elasticsearch_plugin_shop_auto_complete_product_name: 10 | path: /{_locale}/auto-complete/product 11 | defaults: 12 | _controller: bitbag_sylius_elasticsearch_plugin.controller.action.shop.auto_complete_product_name 13 | requirements: 14 | slug: .+ 15 | 16 | bitbag_sylius_elasticsearch_plugin_shop_search: 17 | path: /{_locale}/search 18 | defaults: 19 | _controller: bitbag_sylius_elasticsearch_plugin.controller.action.shop.site_wide_products_search 20 | template: "@BitBagSyliusElasticsearchPlugin/Shop/SiteWideSearch/index.html.twig" 21 | 22 | when@dev: 23 | bitbag_sylius_elasticsearch_plugin_shop_search: 24 | path: /{_locale}/search 25 | requirements: 26 | _locale: ^(?!_profiler).+ 27 | defaults: 28 | _controller: bitbag_sylius_elasticsearch_plugin.controller.action.shop.site_wide_products_search 29 | template: "@BitBagSyliusElasticsearchPlugin/Shop/SiteWideSearch/index.html.twig" 30 | -------------------------------------------------------------------------------- /config/services/api/data_provider.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /config/services/api/request_data_handler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /config/services/api/resolver.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /config/services/context.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /config/services/controller/api.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /config/services/transformer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /config/services/twig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /doc/es_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/doc/es_browser.png -------------------------------------------------------------------------------- /doc/es_results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/doc/es_results.png -------------------------------------------------------------------------------- /doc/installation/attribute-mapping.md: -------------------------------------------------------------------------------- 1 | # Attribute-mapping 2 | 3 | Check the mapping settings in `config/packages/doctrine.yaml`. 4 | ```yaml 5 | doctrine: 6 | ... 7 | orm: 8 | entity_managers: 9 | default: 10 | ... 11 | mappings: 12 | App: 13 | ... 14 | type: attribute 15 | ``` 16 | 17 | Update entity with traits: 18 | ```php 19 | import('vendor/bitbag/coding-standard/ecs.php'); 12 | $config->paths(['src', 'tests']); 13 | }; 14 | -------------------------------------------------------------------------------- /etc/build/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/etc/build/.gitignore -------------------------------------------------------------------------------- /etc/build/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/etc/build/.gitkeep -------------------------------------------------------------------------------- /features/shop/searching_products_by_a_partial_name.feature: -------------------------------------------------------------------------------- 1 | @searching_products 2 | Feature: Filtering products 3 | In order to find a product I am into 4 | As a Customer 5 | I want to be able to filter products by specific criteria 6 | 7 | Background: 8 | Given the store operates on a single channel in "United States" 9 | And the store classifies its products as "Shirts" 10 | And there is a product named "Loose white designer T-Shirt" in the store 11 | And there is a product named "Everyday white basic T-Shirt" in the store 12 | And there is a product named "Ribbed copper slim fit Tee" in the store 13 | And there is a product named "Oversize white cotton T-Shirt" in the store 14 | And there is a product named "Raglan grey & black Tee" in the store 15 | And there is a product named "Sport basic white T-Shirt" in the store 16 | And these products belongs primarily to "Shirts" taxon 17 | And the data is populated to Elasticsearch 18 | 19 | @api 20 | Scenario: Filtering products by name 21 | When I search the products by "shirt" phrase 22 | Then I should see 4 products 23 | -------------------------------------------------------------------------------- /node_modules: -------------------------------------------------------------------------------- 1 | tests/Application/node_modules -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@bitbag/elasticsearch-plugin", 3 | "description": "Elasticsearch plugin for Sylius.", 4 | "repository": "https://github.com/BitBagCommerce/[...].git", 5 | "license": "MIT", 6 | "scripts": { 7 | "dist": "yarn encore production --config-name bitbag-plugin-dist" 8 | }, 9 | "dependencies": { 10 | "node-sass": "7.0.1" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /phpspec.yml.dist: -------------------------------------------------------------------------------- 1 | suites: 2 | main: 3 | namespace: BitBag\SyliusElasticsearchPlugin 4 | psr4_prefix: BitBag\SyliusElasticsearchPlugin 5 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 8 3 | reportUnmatchedIgnoredErrors: false 4 | paths: 5 | - src 6 | 7 | excludePaths: 8 | # Sitemap dependent providers 9 | - 'src/SitemapProvider' 10 | - 'src/Importer/AbstractImporter' 11 | - 'tests/Application/config/bootstrap.php' 12 | - 'tests/Fixture/PageFixtureTest.php' 13 | - 'src/Controller/Helper' 14 | ignoreErrors: 15 | - identifier: missingType.iterableValue 16 | - identifier: missingType.generics 17 | - '#.*NodeParentInterface.*#' 18 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | tests/PHPUnit 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /spec/Controller/RequestDataHandler/PaginationDataHandlerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith( 22 | 9, 23 | ); 24 | } 25 | 26 | function it_is_initializable(): void 27 | { 28 | $this->shouldHaveType(PaginationDataHandler::class); 29 | } 30 | 31 | function it_implements_pagination_data_handler_interface(): void 32 | { 33 | $this->shouldHaveType(PaginationDataHandlerInterface::class); 34 | } 35 | 36 | function it_retrieves_data(): void 37 | { 38 | $this->retrieveData([])->shouldBeEqualTo([ 39 | PaginationDataHandlerInterface::PAGE_INDEX => 1, 40 | PaginationDataHandlerInterface::LIMIT_INDEX => 9, 41 | ]); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /spec/Controller/Response/ItemsResponseSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedThrough('createEmpty'); 21 | } 22 | 23 | function it_can_add_items(): void 24 | { 25 | $this->addItem(new Item( 26 | 'Super cars', 27 | 'McLaren F1', 28 | 'Very quirky super-car', 29 | '/mc-laren/f1', 30 | '$22,000,000.00', 31 | '' 32 | )); 33 | 34 | $this->all()->shouldHaveCount(1); 35 | } 36 | 37 | function it_returns_an_array(): void 38 | { 39 | $this->toArray()->shouldBeArray(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /spec/Exception/TaxonNotFoundExceptionSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType(TaxonNotFoundException::class); 22 | } 23 | 24 | function it_is_an_not_found_exception(): void 25 | { 26 | $this->shouldHaveType(NotFoundHttpException::class); 27 | } 28 | 29 | function it_has_custom_message(): void 30 | { 31 | $this->getMessage()->shouldReturn('Taxon has not been found!'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /spec/Formatter/StringFormatterSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType(StringFormatter::class); 24 | } 25 | 26 | function it_implements_string_formatter_interface(): void 27 | { 28 | $this->shouldHaveType(StringFormatterInterface::class); 29 | } 30 | 31 | function it_formats_to_lowercase_without_spaces(): void 32 | { 33 | $this->formatToLowercaseWithoutSpaces('StrIng in-De-x')->shouldBeEqualTo('string_in_de_x'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spec/PropertyBuilder/ProductDescriptionBuilderSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($productNameNameResolver); 20 | } 21 | 22 | function it_is_initializable(): void 23 | { 24 | $this->shouldHaveType(ProductDescriptionBuilder::class); 25 | $this->shouldHaveType(AbstractBuilder::class); 26 | } 27 | 28 | function it_implements_property_builder_interface(): void 29 | { 30 | $this->shouldHaveType(PropertyBuilderInterface::class); 31 | } 32 | 33 | function it_consumes_event(Document $document, $object): void 34 | { 35 | $event = new PostTransformEvent($document->getWrappedObject(), [], $object->getWrappedObject()); 36 | $this->consumeEvent($event); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /spec/PropertyBuilder/ProductShortDescriptionBuilderSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($productNameNameResolver); 20 | } 21 | 22 | function it_is_initializable(): void 23 | { 24 | $this->shouldHaveType(ProductShortDescriptionBuilder::class); 25 | $this->shouldHaveType(AbstractBuilder::class); 26 | } 27 | 28 | function it_implements_property_builder_interface(): void 29 | { 30 | $this->shouldHaveType(PropertyBuilderInterface::class); 31 | } 32 | 33 | function it_consumes_event(Document $document, $object): void 34 | { 35 | $event = new PostTransformEvent($document->getWrappedObject(), [], $object->getWrappedObject()); 36 | $this->consumeEvent($event); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /spec/PropertyNameResolver/ConcatedNameResolverSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('Book'); 24 | } 25 | 26 | function it_is_initializable(): void 27 | { 28 | $this->shouldHaveType(ConcatedNameResolver::class); 29 | } 30 | 31 | function it_implements_concated_name_resolver_interface(): void 32 | { 33 | $this->shouldHaveType(ConcatedNameResolverInterface::class); 34 | } 35 | 36 | function it_resolves_property_name(): void 37 | { 38 | $this->resolvePropertyName('En')->shouldBeEqualTo('book_en'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /spec/PropertyNameResolver/PriceNameResolverSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('price'); 24 | } 25 | 26 | function it_is_initializable(): void 27 | { 28 | $this->shouldHaveType(PriceNameResolver::class); 29 | } 30 | 31 | function it_implements_price_name_resolver_interface(): void 32 | { 33 | $this->shouldHaveType(PriceNameResolverInterface::class); 34 | } 35 | 36 | function it_resolves_min_price_name(): void 37 | { 38 | $this->resolveMinPriceName()->shouldBeEqualTo('min_price'); 39 | } 40 | 41 | function it_resolves_max_price_name(): void 42 | { 43 | $this->resolveMaxPriceName()->shouldBeEqualTo('max_price'); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /spec/QueryBuilder/HasOptionsQueryBuilderSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType(HasOptionsQueryBuilder::class); 25 | } 26 | 27 | function it_implements_query_builder_interface(): void 28 | { 29 | $this->shouldHaveType(QueryBuilderInterface::class); 30 | } 31 | 32 | function it_builds_query(): void 33 | { 34 | $this->buildQuery([ 35 | 'option_values' => ['XL', 'L'], 36 | 'option' => 'size', 37 | ])->shouldBeAnInstanceOf(BoolQuery::class); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /spec/QueryBuilder/IsEnabledQueryBuilderSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('enabled'); 23 | } 24 | 25 | function it_is_initializable(): void 26 | { 27 | $this->shouldHaveType(IsEnabledQueryBuilder::class); 28 | } 29 | 30 | function it_implements_query_builder_interface(): void 31 | { 32 | $this->shouldHaveType(QueryBuilderInterface::class); 33 | } 34 | 35 | function it_builds_query(): void 36 | { 37 | $this->buildQuery([])->shouldBeAnInstanceOf(Term::class); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /spec/QueryBuilder/ProductsByPartialNameQueryBuilderSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($containsNameQueryBuilder); 23 | } 24 | 25 | function it_is_a_query_builder(): void 26 | { 27 | $this->shouldImplement(QueryBuilderInterface::class); 28 | } 29 | 30 | function it_builds_query( 31 | QueryBuilderInterface $containsNameQueryBuilder, 32 | AbstractQuery $productsQuery 33 | ): void { 34 | $containsNameQueryBuilder->buildQuery([])->willReturn($productsQuery); 35 | 36 | $this->buildQuery([])->shouldBeAnInstanceOf(BoolQuery::class); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /spec/Transformer/Product/SlugTransformerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($router); 23 | } 24 | 25 | function it_is_a_transformer(): void 26 | { 27 | $this->shouldImplement(TransformerInterface::class); 28 | } 29 | 30 | function it_transforms_product_slug_into_route(RouterInterface $router, ProductInterface $product): void 31 | { 32 | $product->getSlug()->willReturn('/super-quirky-shirt'); 33 | 34 | $router->generate('sylius_shop_product_show', ['slug' => '/super-quirky-shirt'])->shouldBeCalled(); 35 | 36 | $this->transform($product); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /spec/Twig/Extension/UnsetArrayElementsExtensionSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType(UnsetArrayElementsExtension::class); 22 | } 23 | 24 | function it_is_a_twig_extension(): void 25 | { 26 | $this->shouldHaveType(AbstractExtension::class); 27 | } 28 | 29 | function it_unset_elments(): void 30 | { 31 | $elements = [ 32 | 'option_l' => 'L', 33 | 'option_xl' => 'XL', 34 | ]; 35 | 36 | $this->unsetElements($elements, ['option_xl'])->shouldBeEqualTo(['option_l' => 'L']); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Api/RequestDataHandler/RequestDataHandler.php: -------------------------------------------------------------------------------- 1 | sortDataHandler->retrieveData($requestData), 31 | $this->paginationDataHandler->retrieveData($requestData), 32 | ['query' => $requestData['query'] ?? ''], 33 | ['facets' => $requestData['facets'] ?? []], 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Api/RequestDataHandler/RequestDataHandlerInterface.php: -------------------------------------------------------------------------------- 1 | addCompilerPass(new AuthenticationManagerPolyfillPass()); 30 | parent::build($container); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/CompilerPass/AuthenticationManagerPolyfillPass.php: -------------------------------------------------------------------------------- 1 | has('security.authentication_manager') 24 | && 25 | true === $container->has('security.authentication.manager') 26 | ) { 27 | $container->setAlias('security.authentication_manager', 'security.authentication.manager'); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Context/ProductAttributesContext.php: -------------------------------------------------------------------------------- 1 | taxonContext->getTaxon(); 28 | 29 | return $this->attributesFinder->findByTaxon($taxon); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Context/ProductAttributesContextInterface.php: -------------------------------------------------------------------------------- 1 | taxonContext->getTaxon(); 28 | 29 | return $this->optionsFinder->findByTaxon($taxon); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Context/ProductOptionsContextInterface.php: -------------------------------------------------------------------------------- 1 | taxonContext->getTaxon(); 28 | 29 | return $this->attributesFinder->findByTaxon($taxon); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Context/TaxonContextInterface.php: -------------------------------------------------------------------------------- 1 | sortDataHandler->retrieveData($requestData), 27 | $this->paginationDataHandler->retrieveData($requestData) 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Controller/RequestDataHandler/SortDataHandlerInterface.php: -------------------------------------------------------------------------------- 1 | shopProductListDataHandler->retrieveData($requestData), 28 | $this->shopProductsSortDataHandler->retrieveData($requestData), 29 | $this->paginationDataHandler->retrieveData($requestData) 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Controller/Response/ItemsResponse.php: -------------------------------------------------------------------------------- 1 | items[] = $item; 33 | } 34 | 35 | public function all(): \Traversable 36 | { 37 | foreach ($this->items as $item) { 38 | yield $item->toArray(); 39 | } 40 | } 41 | 42 | public function toArray(): array 43 | { 44 | return ['items' => iterator_to_array($this->all())]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/EventListener/ProductTaxonIndexListener.php: -------------------------------------------------------------------------------- 1 | getProduct(); 32 | 33 | $this->resourceRefresher->refresh($product, $this->objectPersister); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/EventListener/ResourceIndexListenerInterface.php: -------------------------------------------------------------------------------- 1 | facets[$facetId] = $facet; 23 | } 24 | 25 | /** 26 | * @return FacetInterface[] 27 | */ 28 | public function getFacets(): array 29 | { 30 | return $this->facets; 31 | } 32 | 33 | public function getFacetById(string $facetId): FacetInterface 34 | { 35 | if (!array_key_exists($facetId, $this->facets)) { 36 | throw new FacetNotFoundException(sprintf('Cannot find facet with ID "%s" in registry.', $facetId)); 37 | } 38 | 39 | return $this->facets[$facetId]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Facet/RegistryInterface.php: -------------------------------------------------------------------------------- 1 | $namePart]; 30 | /** @var AbstractQuery $query */ 31 | $query = $this->queryBuilder->buildQuery($data); 32 | 33 | return $this->productsFinder->find($query); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Finder/NamedProductsFinderInterface.php: -------------------------------------------------------------------------------- 1 | taxonsProperty] = strtolower((string) $taxon->getCode()); 34 | 35 | /** @var AbstractQuery $query */ 36 | $query = $this->attributesByTaxonQueryBuilder->buildQuery($data); 37 | 38 | return $this->attributesFinder->find($query, $this->filterMax); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Finder/ProductAttributesFinderInterface.php: -------------------------------------------------------------------------------- 1 | taxonsProperty] = strtolower((string) $taxon->getCode()); 34 | 35 | /** @var AbstractQuery $query */ 36 | $query = $this->productOptionsByTaxonQueryBuilder->buildQuery($data); 37 | 38 | return $this->optionsFinder->find($query, $this->filterMax); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Finder/ProductOptionsFinderInterface.php: -------------------------------------------------------------------------------- 1 | setDefaults([ 23 | 'data_class', null, 24 | 'csrf_protection' => false, 25 | 'allow_extra_fields' => true, 26 | ]); 27 | } 28 | 29 | public function getBlockPrefix(): string 30 | { 31 | return ''; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Form/Type/ChoiceMapper/AttributesMapper/AttributesMapperCollectorInterface.php: -------------------------------------------------------------------------------- 1 | format(self::CHOICE_DATE_FORMAT); 33 | $value = $productAttributeValue['value']->format(self::VALUE_DATE_FORMAT); 34 | $choices[$choice] = $value; 35 | } 36 | 37 | return $choices; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Form/Type/ChoiceMapper/AttributesMapper/AttributesTypeDateTimeMapper.php: -------------------------------------------------------------------------------- 1 | format('d-m-Y H:i'); 29 | $value = $productAttributeValue['value']->format('Y-m-d H:i:s.sss'); 30 | $choices[$choice] = $value; 31 | } 32 | 33 | return $choices; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Form/Type/ChoiceMapper/AttributesMapper/AttributesTypePercentMapper.php: -------------------------------------------------------------------------------- 1 | setDefaults([ 25 | 'label' => 'bitbag_sylius_elasticsearch_plugin.ui.name', 26 | 'required' => false, 27 | ]); 28 | } 29 | 30 | public function getParent(): string 31 | { 32 | return TextType::class; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Formatter/StringFormatter.php: -------------------------------------------------------------------------------- 1 | addVariant($this); 23 | 24 | return $product; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Model/Search.php: -------------------------------------------------------------------------------- 1 | query; 24 | } 25 | 26 | public function setQuery(?string $query): void 27 | { 28 | $this->query = $query; 29 | } 30 | 31 | public function getFacets(): array 32 | { 33 | return $this->facets; 34 | } 35 | 36 | public function setFacets(array $facets): void 37 | { 38 | $this->facets = $facets; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Model/SearchBox.php: -------------------------------------------------------------------------------- 1 | query; 22 | } 23 | 24 | public function setQuery(?string $query): void 25 | { 26 | $this->query = $query; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/PropertyBuilder/AbstractBuilder.php: -------------------------------------------------------------------------------- 1 | getObject(); 26 | 27 | if (!$model instanceof $supportedModelClass || ($model instanceof ToggleableInterface && !$model->isEnabled())) { 28 | return; 29 | } 30 | 31 | $document = $event->getDocument(); 32 | 33 | $callback($model, $document); 34 | } 35 | 36 | public static function getSubscribedEvents(): array 37 | { 38 | return [ 39 | PostTransformEvent::class => 'consumeEvent', 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/PropertyBuilder/ChannelsBuilder.php: -------------------------------------------------------------------------------- 1 | buildProperty( 29 | $event, 30 | ProductInterface::class, 31 | function (ProductInterface $product, Document $document): void { 32 | $channels = []; 33 | 34 | foreach ($product->getChannels() as $channel) { 35 | $channels[] = $channel->getCode(); 36 | } 37 | 38 | $document->set($this->channelsProperty, $channels); 39 | } 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/PropertyBuilder/Mapper/ProductTaxonsMapper.php: -------------------------------------------------------------------------------- 1 | getTaxons() as $taxon) { 29 | $taxons[] = $taxon->getCode(); 30 | 31 | if (true === $this->includeAllDescendants) { 32 | foreach ($taxon->getAncestors() as $ancestor) { 33 | $taxons[] = $ancestor->getCode(); 34 | } 35 | } 36 | } 37 | 38 | return array_values(array_unique($taxons)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/PropertyBuilder/Mapper/ProductTaxonsMapperInterface.php: -------------------------------------------------------------------------------- 1 | buildProperty( 26 | $event, 27 | ProductInterface::class, 28 | function (ProductInterface $product, Document $document): void { 29 | $document->set(self::PROPERTY_NAME, $product->getCode()); 30 | } 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/PropertyBuilder/ProductCreatedAtPropertyBuilder.php: -------------------------------------------------------------------------------- 1 | buildProperty( 30 | $event, 31 | ProductInterface::class, 32 | function (ProductInterface $product, Document $document): void { 33 | Assert::notNull($product->getCreatedAt()); 34 | $createdAt = (int) $product->getCreatedAt()->format('U'); 35 | 36 | $document->set($this->createdAtProperty, $createdAt); 37 | } 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/PropertyBuilder/ProductTaxonsBuilder.php: -------------------------------------------------------------------------------- 1 | buildProperty( 31 | $event, 32 | ProductInterface::class, 33 | function (ProductInterface $product, Document $document): void { 34 | $taxons = $this->productTaxonsMapper->mapToUniqueCodes($product); 35 | 36 | $document->set($this->taxonsProperty, $taxons); 37 | } 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/PropertyBuilder/PropertyBuilderInterface.php: -------------------------------------------------------------------------------- 1 | propertyPrefix . '_' . $suffix); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/PropertyNameResolver/ConcatedNameResolverInterface.php: -------------------------------------------------------------------------------- 1 | pricePropertyPrefix; 25 | } 26 | 27 | public function resolveMaxPriceName(): string 28 | { 29 | return 'max_' . $this->pricePropertyPrefix; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/PropertyNameResolver/PriceNameResolverInterface.php: -------------------------------------------------------------------------------- 1 | propertyNameResolvers[] = $propertyNameResolver; 23 | } 24 | 25 | /** 26 | * @return ConcatedNameResolverInterface[] 27 | */ 28 | public function getPropertyNameResolvers(): array 29 | { 30 | return $this->propertyNameResolvers; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/PropertyNameResolver/SearchPropertyNameResolverRegistryInterface.php: -------------------------------------------------------------------------------- 1 | setTerm($attribute, $attributeValue); 38 | $attributeQuery->addShould($termQuery); 39 | } 40 | 41 | return $attributeQuery; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/QueryBuilder/AttributesQueryBuilder/AttributesTypeNumberQueryBuilder.php: -------------------------------------------------------------------------------- 1 | setTerm($attribute, $attributeValue); 39 | $attributeQuery->addShould($termQuery); 40 | } 41 | 42 | return $attributeQuery; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/QueryBuilder/AttributesQueryBuilder/AttributesTypeTextQueryBuilder.php: -------------------------------------------------------------------------------- 1 | setTerm($attribute, $attributeValue); 39 | $attributeQuery->addShould($termQuery); 40 | } 41 | 42 | return $attributeQuery; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/QueryBuilder/FormQueryBuilder/SiteWideFacetsQueryBuilderInterface.php: -------------------------------------------------------------------------------- 1 | channelsProperty)); 30 | /** @var string $channelCode */ 31 | $channelCode = $this->channelContext->getChannel()->getCode(); 32 | $channelQuery->setTerms([$channelCode]); 33 | 34 | return $channelQuery; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/QueryBuilder/HasOptionsQueryBuilder.php: -------------------------------------------------------------------------------- 1 | setTerm($data['option'], $optionValue); 28 | $optionQuery->addShould($termQuery); 29 | } 30 | 31 | return $optionQuery; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/QueryBuilder/HasTaxonQueryBuilder.php: -------------------------------------------------------------------------------- 1 | taxonsProperty]) { 28 | return null; 29 | } 30 | 31 | $taxonQuery = new Terms($this->taxonsProperty); 32 | $taxonQuery->setTerms([$taxonCode]); 33 | 34 | return $taxonQuery; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/QueryBuilder/IsEnabledQueryBuilder.php: -------------------------------------------------------------------------------- 1 | setTerm($this->enabledProperty, true); 29 | 30 | return $enabledQuery; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/QueryBuilder/ProductAttributesByTaxonQueryBuilder.php: -------------------------------------------------------------------------------- 1 | hasTaxonQueryBuilder->buildQuery($data); 30 | 31 | Assert::notNull($taxonQuery); 32 | 33 | $boolQuery->addMust($taxonQuery); 34 | 35 | return $boolQuery; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/QueryBuilder/ProductOptionsByTaxonQueryBuilder.php: -------------------------------------------------------------------------------- 1 | hasTaxonQueryBuilder->buildQuery($data); 30 | 31 | Assert::notNull($taxonQuery); 32 | 33 | $boolQuery->addMust($taxonQuery); 34 | 35 | return $boolQuery; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/QueryBuilder/ProductsByPartialNameQueryBuilder.php: -------------------------------------------------------------------------------- 1 | containsNameQueryBuilder->buildQuery($data); 30 | 31 | if (null !== $nameQuery) { 32 | $boolQuery->addFilter($nameQuery); 33 | } 34 | 35 | return $boolQuery; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/QueryBuilder/QueryBuilderInterface.php: -------------------------------------------------------------------------------- 1 | getId()) { 23 | $objectPersister->deleteById($resource->getId()); 24 | $objectPersister->replaceOne($resource); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Refresher/ResourceRefresherInterface.php: -------------------------------------------------------------------------------- 1 | getSlug()) { 28 | return null; 29 | } 30 | 31 | return $this->router->generate('sylius_shop_product_show', ['slug' => $product->getSlug()]); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Transformer/Product/TransformerInterface.php: -------------------------------------------------------------------------------- 1 | formFactory->create(SearchType::class)->createView(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Twig/Extension/UnsetArrayElementsExtension.php: -------------------------------------------------------------------------------- 1 | 2 | {% hook 'search_form' %} 3 | 4 | -------------------------------------------------------------------------------- /templates/Shop/SearchForm/searchForm.html.twig: -------------------------------------------------------------------------------- 1 | {% form_theme search_form '@SyliusShop/form/theme.html.twig' %} 2 | 3 | {{ form_start(search_form, {'action': path('bitbag_sylius_elasticsearch_plugin_shop_search')}) }} 4 |
5 | {{ form_widget(search_form.query) }} 6 | 9 |
10 | {{ form_end(search_form, {'render_rest': false}) }} 11 |
12 | -------------------------------------------------------------------------------- /templates/Shop/SiteWideSearch/content/body.html.twig: -------------------------------------------------------------------------------- 1 | {% set form = hookable_metadata.context.search_form %} 2 | {% form_theme form '@SyliusShop/form/theme.html.twig' %} 3 | 4 |
5 | {{ form_start(form, {'attr': {'id': form.vars.id}}) }} 6 | 7 | {% hook 'body' %} 8 | {{ form_end(form, {render_rest: false}) }} 9 |
10 | -------------------------------------------------------------------------------- /templates/Shop/SiteWideSearch/content/body/main/limit/menu.html.twig: -------------------------------------------------------------------------------- 1 | {% set route = app.request.attributes.get('_route') %} 2 | {% set route_parameters = app.request.query.all|unset_elements(['order_by', 'sort', 'page']) %} 3 | {% set slug = app.request.get('slug') %} 4 | 5 | 10 | -------------------------------------------------------------------------------- /templates/Shop/SiteWideSearch/content/body/main/limit/toggle.html.twig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/Shop/SiteWideSearch/content/body/main/pagination.html.twig: -------------------------------------------------------------------------------- 1 | {% set products = hookable_metadata.context.products is defined and hookable_metadata.context.products is not empty ? hookable_metadata.context.products : null %} 2 | {% import '@SyliusShop/shared/pagination/pagination.html.twig' as pagination %} 3 | 4 | {% if products is not null %} 5 | {{ pagination.simple(products) }} 6 | {% endif %} -------------------------------------------------------------------------------- /templates/Shop/SiteWideSearch/content/body/main/products.html.twig: -------------------------------------------------------------------------------- 1 | {% import '@SyliusShop/shared/messages.html.twig' as messages %} 2 | 3 | {% set products = hookable_metadata.context.products is defined and hookable_metadata.context.products is not empty ? hookable_metadata.context.products : [] %} 4 | 5 | {% if products|length > 0 %} 6 |
7 | {% for product in products %} 8 | {{ component('sylius_shop:product:card', { product: product, template: '@SyliusShop/product/common/card.html.twig' }) }} 9 | {% endfor %} 10 |
11 | {% else %} 12 | {{ messages.info('sylius.ui.no_results_to_display') }} 13 | {% endif %} 14 | -------------------------------------------------------------------------------- /templates/Shop/SiteWideSearch/content/body/main/search.html.twig: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | {% hook 'search' %} 5 |
6 |
7 |
8 | -------------------------------------------------------------------------------- /templates/Shop/SiteWideSearch/content/body/main/sorting/item.html.twig: -------------------------------------------------------------------------------- 1 | {% set route = hookable_metadata.context.route %} 2 | {% set route_parameters = hookable_metadata.context.route_parameters %} 3 | {% set slug = app.request.get('slug') %} 4 | {% set order_by = hookable_metadata.configuration.order_by %} 5 | {% set sort = hookable_metadata.configuration.sort %} 6 | {% set title = hookable_metadata.configuration.title|trans %} 7 | 8 | {{ title }} 9 | -------------------------------------------------------------------------------- /templates/Shop/SiteWideSearch/content/body/sidebar/facets.html.twig: -------------------------------------------------------------------------------- 1 | {% set form = hookable_metadata.context.search_form %} 2 | 3 | {% form_theme form '@SyliusShop/form/theme.html.twig' %} 4 | 5 |
6 | {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} 7 | 8 | {{ form_row(form.query, {'attr': {'style': 'display: none'}}) }} 9 | 10 | {% if form.facets is defined %} 11 |
12 | {% for facet in form.facets %} 13 | {{ form_row(facet) }} 14 | {% endfor %} 15 |
16 | {% endif %} 17 | 18 | {{ form_end(form, {render_rest: false}) }} 19 |
20 | -------------------------------------------------------------------------------- /templates/Shop/SiteWideSearch/content/breadcrumbs.html.twig: -------------------------------------------------------------------------------- 1 | {% from '@SyliusShop/shared/breadcrumbs.html.twig' import breadcrumbs as breadcrumbs %} 2 | 3 | {{ breadcrumbs([ 4 | { label: 'sylius.ui.home'|trans, path: path('sylius_shop_homepage'), active: false }, 5 | { label: 'bitbag_sylius_elasticsearch_plugin.ui.search_header'|trans, active: true } 6 | ]) }} 7 | -------------------------------------------------------------------------------- /templates/Shop/SiteWideSearch/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@SyliusShop/shared/layout/base.html.twig' %} 2 | 3 | {% block content %} 4 | {% hook 'bitbag.sylius_elasticsearch_plugin.site_wide_search.index' with { products, search_form } %} 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /templates/Shop/TaxonProductsSearch/content/body.html.twig: -------------------------------------------------------------------------------- 1 | {% set form = hookable_metadata.context.search_form %} 2 | {% form_theme form '@SyliusShop/form/theme.html.twig' %} 3 | 4 |
5 | {{ form_start(form, {'attr': {'id': form.vars.id}}) }} 6 | 7 | {% hook 'body' %} 8 | {{ form_end(form, {render_rest: false}) }} 9 |
10 | -------------------------------------------------------------------------------- /templates/Shop/TaxonProductsSearch/content/body/main/limit/menu.html.twig: -------------------------------------------------------------------------------- 1 | {% set route = app.request.attributes.get('_route') %} 2 | {% set route_parameters = app.request.query.all|unset_elements(['order_by', 'sort', 'page']) %} 3 | {% set slug = app.request.get('slug') %} 4 | 5 | 10 | -------------------------------------------------------------------------------- /templates/Shop/TaxonProductsSearch/content/body/main/limit/toggle.html.twig: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /templates/Shop/TaxonProductsSearch/content/body/main/pagination.html.twig: -------------------------------------------------------------------------------- 1 | {% set products = hookable_metadata.context.products is defined and hookable_metadata.context.products is not empty ? hookable_metadata.context.products : null %} 2 | {% import '@SyliusShop/shared/pagination/pagination.html.twig' as pagination %} 3 | 4 | {% if products is not null %} 5 | {{ pagination.simple(products) }} 6 | {% endif %} 7 | -------------------------------------------------------------------------------- /templates/Shop/TaxonProductsSearch/content/body/main/products.html.twig: -------------------------------------------------------------------------------- 1 | {% import '@SyliusShop/shared/messages.html.twig' as messages %} 2 | 3 | {% set products = hookable_metadata.context.products is defined and hookable_metadata.context.products is not empty ? hookable_metadata.context.products : [] %} 4 | 5 | {% if products|length > 0 %} 6 |
7 | {% for product in products %} 8 | {{ component('sylius_shop:product:card', { product: product, template: '@SyliusShop/product/common/card.html.twig' }) }} 9 | {% endfor %} 10 |
11 | {% else %} 12 | {{ messages.info('sylius.ui.no_results_to_display') }} 13 | {% endif %} 14 | -------------------------------------------------------------------------------- /templates/Shop/TaxonProductsSearch/content/body/main/search.html.twig: -------------------------------------------------------------------------------- 1 | {% set form = hookable_metadata.context.form %} 2 | {% set taxon = hookable_metadata.context.taxon %} 3 | {% set slug = taxon.slug %} 4 | 5 | {{ form_start(form, {'action': path('bitbag_sylius_elasticsearch_plugin_shop_taxon_products', {'slug': slug})}) }} 6 |
7 |
8 | {{ form_widget(form.name, {'attr': {'placeholder': 'bitbag_sylius_elasticsearch_plugin.ui.search_box.search_in_taxon', 'class': 'prompt'}}) }} 9 | 10 | 13 |
14 |
15 | {{ form_end(form, {'render_rest': false}) }} 16 | -------------------------------------------------------------------------------- /templates/Shop/TaxonProductsSearch/content/body/main/sorting/item.html.twig: -------------------------------------------------------------------------------- 1 | {% set route = hookable_metadata.context.route %} 2 | {% set route_parameters = hookable_metadata.context.route_parameters %} 3 | {% set slug = app.request.get('slug') %} 4 | {% set order_by = hookable_metadata.configuration.order_by %} 5 | {% set sort = hookable_metadata.configuration.sort %} 6 | {% set title = hookable_metadata.configuration.title|trans %} 7 | 8 | {{ title }} 9 | -------------------------------------------------------------------------------- /templates/Shop/TaxonProductsSearch/content/body/sidebar/facets.html.twig: -------------------------------------------------------------------------------- 1 | {% set form = hookable_metadata.context.form %} 2 | 3 | {% form_theme form '@SyliusShop/form/theme.html.twig' %} 4 | 5 |
6 | {{ form_start(form, {'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} 7 | {% if form.facets is defined %} 8 |
9 | {% for facet in form.facets %} 10 | {% if facet.vars.name != 'taxon' %} 11 | {{ form_row(facet) }} 12 | {% endif %} 13 | {% endfor %} 14 |
15 | {% endif %} 16 | 17 | {{ form_end(form, {render_rest: false}) }} 18 |
19 | -------------------------------------------------------------------------------- /templates/Shop/TaxonProductsSearch/content/breadcrumbs.html.twig: -------------------------------------------------------------------------------- 1 | {% from '@SyliusShop/shared/breadcrumbs.html.twig' import breadcrumbs as breadcrumbs %} 2 | 3 | {% set taxon = hookable_metadata.context.taxon %} 4 | {% set items = [{ path: path('sylius_shop_homepage'), label: 'sylius.ui.home'|trans }] %} 5 | {% set ancestors = taxon.ancestors|reverse %} 6 | 7 | {% for ancestor in ancestors %} 8 | {% if ancestor.isRoot() or not ancestor.enabled %} 9 | {% set items = items|merge([{ label: ancestor.name }]) %} 10 | {% else %} 11 | {% set items = items|merge([{ path: path('sylius_shop_product_index', {'slug': ancestor.slug, '_locale': ancestor.translation.locale}), label: ancestor.name }]) %} 12 | {% endif %} 13 | {% endfor %} 14 | 15 | {% set items = items|merge([{ label: taxon.name, active: true }]) %} 16 | 17 | {{ breadcrumbs(items) }} 18 | -------------------------------------------------------------------------------- /templates/Shop/TaxonProductsSearch/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@SyliusShop/shared/layout/base.html.twig' %} 2 | 3 | {% block content %} 4 | {% hook 'bitbag.sylius_elasticsearch_plugin.taxon_products_search.index' with { products, form } %} 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /tests/Application/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "targets": { 5 | "node": "6" 6 | }, 7 | "useBuiltIns": true 8 | }] 9 | ], 10 | "plugins": [ 11 | ["transform-object-rest-spread", { 12 | "useBuiltIns": true 13 | }] 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/Application/.env.test: -------------------------------------------------------------------------------- 1 | APP_SECRET='ch4mb3r0f5ecr3ts' 2 | 3 | KERNEL_CLASS='Tests\BitBag\SyliusElasticsearchPlugin\Application\Kernel' 4 | -------------------------------------------------------------------------------- /tests/Application/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'airbnb-base', 3 | env: { 4 | node: true, 5 | }, 6 | rules: { 7 | 'object-shorthand': ['error', 'always', { 8 | avoidQuotes: true, 9 | avoidExplicitReturnArrows: true, 10 | }], 11 | 'function-paren-newline': ['error', 'consistent'], 12 | 'max-len': ['warn', 120, 2, { 13 | ignoreUrls: true, 14 | ignoreComments: false, 15 | ignoreRegExpLiterals: true, 16 | ignoreStrings: true, 17 | ignoreTemplateLiterals: true, 18 | }], 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /tests/Application/.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | @ @BitBagCommerce 2 | * @Sylius/core-team -------------------------------------------------------------------------------- /tests/Application/.gitignore: -------------------------------------------------------------------------------- 1 | /public/assets 2 | /public/build 3 | /public/css 4 | /public/js 5 | /public/media/* 6 | !/public/media/image/ 7 | /public/media/image/* 8 | !/public/media/image/.gitignore 9 | 10 | /node_modules 11 | package-lock.json 12 | 13 | ###> symfony/framework-bundle ### 14 | /.env.*.local 15 | /.env.local 16 | /.env.local.php 17 | /public/bundles 18 | /var/ 19 | /vendor/ 20 | ###< symfony/framework-bundle ### 21 | 22 | ###> symfony/web-server-bundle ### 23 | /.web-server-pid 24 | ###< symfony/web-server-bundle ### 25 | 26 | -------------------------------------------------------------------------------- /tests/Application/Kernel.php: -------------------------------------------------------------------------------- 1 | getParameterOption(['--env', '-e'], null, true)) { 19 | putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env); 20 | } 21 | 22 | if ($input->hasParameterOption('--no-debug', true)) { 23 | putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0'); 24 | } 25 | 26 | require dirname(__DIR__).'/config/bootstrap.php'; 27 | 28 | if ($_SERVER['APP_DEBUG']) { 29 | umask(0000); 30 | 31 | if (class_exists(Debug::class)) { 32 | Debug::enable(); 33 | } 34 | } 35 | 36 | $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); 37 | $application = new Application($kernel); 38 | $application->run($input); 39 | -------------------------------------------------------------------------------- /tests/Application/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sylius/plugin-elasticsearch-test-application", 3 | "description": "Sylius application for plugin testing purposes (composer.json needed for project dir resolving)", 4 | "license": "MIT", 5 | "require": { 6 | "symfony/webpack-encore-bundle": "^1.13" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/Application/config/api_platform/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/tests/Application/config/api_platform/.gitkeep -------------------------------------------------------------------------------- /tests/Application/config/bootstrap.php: -------------------------------------------------------------------------------- 1 | =1.2) 11 | if (is_array($env = @include dirname(__DIR__) . '/.env.local.php')) { 12 | $_SERVER += $env; 13 | $_ENV += $env; 14 | } elseif (!class_exists(Dotenv::class)) { 15 | throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); 16 | } else { 17 | // load all the .env files 18 | (new Dotenv())->loadEnv(dirname(__DIR__) . '/.env'); 19 | } 20 | 21 | $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; 22 | $_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; 23 | $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], \FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; 24 | -------------------------------------------------------------------------------- /tests/Application/config/jwt/public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6QkmF/Xi5nAYb8Kzr7qC 3 | d63V2K+d/nCXbpDUKKDPJAqOtTlMoQSuJRLNnhhp7z1i/Cp4Bhifr20Pu2dq8JYg 4 | 6pRT4ctqvYb/MXxAaPZc3EcBC0S6AhgKO/fDvR3LcqYqGJmQQOXZvxTsgqongdvV 5 | 4XbqFBMMgngyayoBk0VKTaI/s+LQhIce+1QaxbAI0+/zbR0hZ1hWT73orJi3do+1 6 | TBzQol+V7WGa8LlJfmgM56qO3BmVkeTDMBc27pGp6g3+Oufk/l29jEGJlUT9yu7Q 7 | BRhaQTWNVASa2aD+AKjVBzJh53O2zD8slAbjF1M9U7bbWN28Sv+xC/dUz0q9HnPu 8 | RsY2tnwryqTyYn/Hf2xyP3/KvjJ6oslAwemu5JirdJkO7KVQAthWG42gLuhZg3ks 9 | cSZhCLZH7nO2UDsf+2ZZgdbhpYZwR4gDRfNt7GKWXnWZOz9Uw1yVCPgylyZRZwg8 10 | l0y9aABdj3379I22icrwpMZbAgkyxNSV6UNJuxZksLUoP3i9OvXYgPYU9E4tU/Ul 11 | Dm/T1rGSReGoPkU1YQnI50bq7p1byIoUu2scTflvpTVI5a7zULkS1tg60xk7vBRC 12 | aBc7nr4UEtA235N6uLtcGxH11WBMwsKX69sSU0sQdC4Sk25zXM2gc8R1XV9K3qz2 13 | wQorQRlCwrkG44VRDgbFH+8CAwEAAQ== 14 | -----END PUBLIC KEY----- 15 | -------------------------------------------------------------------------------- /tests/Application/config/packages/_sylius.yaml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: "@SyliusCoreBundle/Resources/config/app/config.yml" } 3 | 4 | - { resource: "@SyliusPayumBundle/Resources/config/app/config.yaml" } 5 | 6 | - { resource: "@SyliusAdminBundle/Resources/config/app/config.yml" } 7 | 8 | - { resource: "@SyliusShopBundle/Resources/config/app/config.yml" } 9 | 10 | - { resource: "@SyliusApiBundle/Resources/config/app/config.yaml" } 11 | 12 | parameters: 13 | sylius_core.public_dir: '%kernel.project_dir%/public' 14 | 15 | sylius_shop: 16 | product_grid: 17 | include_all_descendants: true 18 | 19 | sylius_api: 20 | enabled: true 21 | 22 | sylius_twig_hooks: 23 | hooks: 24 | 'sylius_shop.base#stylesheets': 25 | app_styles: 26 | template: 'shop/stylesheets.html.twig' 27 | 'sylius_shop.base#javascripts': 28 | app_javascripts: 29 | template: 'shop/javascripts.html.twig' 30 | -------------------------------------------------------------------------------- /tests/Application/config/packages/assets.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | assets: 3 | packages: 4 | shop: 5 | json_manifest_path: '%kernel.project_dir%/public/build/shop/manifest.json' 6 | admin: 7 | json_manifest_path: '%kernel.project_dir%/public/build/admin/manifest.json' 8 | elasticsearch_shop: 9 | json_manifest_path: '%kernel.project_dir%/public/build/bitbag/elasticsearch/shop/manifest.json' 10 | elasticsearch_admin: 11 | json_manifest_path: '%kernel.project_dir%/public/build/bitbag/elasticsearch/admin/manifest.json' 12 | -------------------------------------------------------------------------------- /tests/Application/config/packages/bitbag_sylius_elasticsearch_plugin.yaml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: "@BitBagSyliusElasticsearchPlugin/config/config.yml" } 3 | -------------------------------------------------------------------------------- /tests/Application/config/packages/dev/framework.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | profiler: { only_exceptions: false } 3 | -------------------------------------------------------------------------------- /tests/Application/config/packages/dev/monolog.yaml: -------------------------------------------------------------------------------- 1 | monolog: 2 | handlers: 3 | main: 4 | type: stream 5 | path: "%kernel.logs_dir%/%kernel.environment%.log" 6 | level: debug 7 | firephp: 8 | type: firephp 9 | level: info 10 | -------------------------------------------------------------------------------- /tests/Application/config/packages/dev/nelmio_alice.yaml: -------------------------------------------------------------------------------- 1 | nelmio_alice: 2 | functions_blacklist: 3 | - 'current' -------------------------------------------------------------------------------- /tests/Application/config/packages/dev/routing.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | router: 3 | strict_requirements: true 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/dev/web_profiler.yaml: -------------------------------------------------------------------------------- 1 | web_profiler: 2 | toolbar: true 3 | intercept_redirects: false 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/doctrine.yaml: -------------------------------------------------------------------------------- 1 | parameters: 2 | # Adds a fallback DATABASE_URL if the env var is not set. 3 | # This allows you to run cache:warmup even if your 4 | # environment variables are not available yet. 5 | # You should not need to change this value. 6 | env(DATABASE_URL): '' 7 | 8 | doctrine: 9 | dbal: 10 | driver: 'pdo_mysql' 11 | server_version: '5.7' 12 | charset: UTF8 13 | 14 | url: '%env(resolve:DATABASE_URL)%' 15 | -------------------------------------------------------------------------------- /tests/Application/config/packages/doctrine_migrations.yaml: -------------------------------------------------------------------------------- 1 | doctrine_migrations: 2 | storage: 3 | table_storage: 4 | table_name: sylius_migrations 5 | -------------------------------------------------------------------------------- /tests/Application/config/packages/fos_elastica.yaml: -------------------------------------------------------------------------------- 1 | fos_elastica: 2 | clients: 3 | default: { url: '%env(ELASTICSEARCH_URL)%' } 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/framework.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | secret: '%env(APP_SECRET)%' 3 | form: true 4 | csrf_protection: true 5 | session: 6 | handler_id: ~ 7 | ide: phpstorm 8 | 9 | -------------------------------------------------------------------------------- /tests/Application/config/packages/http_discovery.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | Psr\Http\Message\RequestFactoryInterface: '@http_discovery.psr17_factory' 3 | Psr\Http\Message\ResponseFactoryInterface: '@http_discovery.psr17_factory' 4 | Psr\Http\Message\ServerRequestFactoryInterface: '@http_discovery.psr17_factory' 5 | Psr\Http\Message\StreamFactoryInterface: '@http_discovery.psr17_factory' 6 | Psr\Http\Message\UploadedFileFactoryInterface: '@http_discovery.psr17_factory' 7 | Psr\Http\Message\UriFactoryInterface: '@http_discovery.psr17_factory' 8 | 9 | http_discovery.psr17_factory: 10 | class: Http\Discovery\Psr17Factory 11 | -------------------------------------------------------------------------------- /tests/Application/config/packages/lexik_jwt_authentication.yaml: -------------------------------------------------------------------------------- 1 | lexik_jwt_authentication: 2 | secret_key: '%env(resolve:JWT_SECRET_KEY)%' 3 | public_key: '%env(resolve:JWT_PUBLIC_KEY)%' 4 | pass_phrase: '%env(JWT_PASSPHRASE)%' 5 | -------------------------------------------------------------------------------- /tests/Application/config/packages/liip_imagine.yaml: -------------------------------------------------------------------------------- 1 | liip_imagine: 2 | resolvers: 3 | default: 4 | web_path: 5 | web_root: "%kernel.project_dir%/public" 6 | cache_prefix: "media/cache" 7 | -------------------------------------------------------------------------------- /tests/Application/config/packages/mailer.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | mailer: 3 | dsn: '%env(MAILER_DSN)%' 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/prod/doctrine.yaml: -------------------------------------------------------------------------------- 1 | doctrine: 2 | orm: 3 | metadata_cache_driver: 4 | type: service 5 | id: doctrine.system_cache_provider 6 | query_cache_driver: 7 | type: service 8 | id: doctrine.system_cache_provider 9 | result_cache_driver: 10 | type: service 11 | id: doctrine.result_cache_provider 12 | 13 | services: 14 | doctrine.result_cache_provider: 15 | class: Symfony\Component\Cache\DoctrineProvider 16 | public: false 17 | arguments: 18 | - '@doctrine.result_cache_pool' 19 | doctrine.system_cache_provider: 20 | class: Symfony\Component\Cache\DoctrineProvider 21 | public: false 22 | arguments: 23 | - '@doctrine.system_cache_pool' 24 | 25 | framework: 26 | cache: 27 | pools: 28 | doctrine.result_cache_pool: 29 | adapter: cache.app 30 | doctrine.system_cache_pool: 31 | adapter: cache.system 32 | -------------------------------------------------------------------------------- /tests/Application/config/packages/prod/monolog.yaml: -------------------------------------------------------------------------------- 1 | monolog: 2 | handlers: 3 | main: 4 | type: fingers_crossed 5 | action_level: error 6 | handler: nested 7 | nested: 8 | type: stream 9 | path: "%kernel.logs_dir%/%kernel.environment%.log" 10 | level: debug 11 | -------------------------------------------------------------------------------- /tests/Application/config/packages/routing.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | router: 3 | strict_requirements: ~ 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/staging/monolog.yaml: -------------------------------------------------------------------------------- 1 | monolog: 2 | handlers: 3 | main: 4 | type: fingers_crossed 5 | action_level: error 6 | handler: nested 7 | nested: 8 | type: stream 9 | path: "%kernel.logs_dir%/%kernel.environment%.log" 10 | level: debug 11 | -------------------------------------------------------------------------------- /tests/Application/config/packages/stof_doctrine_extensions.yaml: -------------------------------------------------------------------------------- 1 | # Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html 2 | # See the official DoctrineExtensions documentation for more details: https://github.com/Atlantic18/DoctrineExtensions/tree/master/doc/ 3 | stof_doctrine_extensions: 4 | default_locale: '%locale%' 5 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test/fidry_alice_data_fixtures.yaml: -------------------------------------------------------------------------------- 1 | fidry_alice_data_fixtures: 2 | default_purge_mode: no_purge -------------------------------------------------------------------------------- /tests/Application/config/packages/test/framework.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | test: ~ 3 | session: 4 | storage_factory_id: session.storage.factory.mock_file 5 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test/mailer.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | cache: 3 | pools: 4 | test.mailer_pool: 5 | adapter: cache.adapter.filesystem -------------------------------------------------------------------------------- /tests/Application/config/packages/test/monolog.yaml: -------------------------------------------------------------------------------- 1 | monolog: 2 | handlers: 3 | main: 4 | type: stream 5 | path: "%kernel.logs_dir%/%kernel.environment%.log" 6 | level: error 7 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test/nelmio_alice.yaml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: ../dev/nelmio_alice.yaml } -------------------------------------------------------------------------------- /tests/Application/config/packages/test/security.yaml: -------------------------------------------------------------------------------- 1 | security: 2 | password_hashers: 3 | sha512: sha512 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test/sylius_theme.yaml: -------------------------------------------------------------------------------- 1 | sylius_theme: 2 | sources: 3 | test: ~ 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test/sylius_uploader.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | Sylius\Component\Core\Generator\ImagePathGeneratorInterface: 3 | class: Sylius\Behat\Service\Generator\UploadedImagePathGenerator 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test/web_profiler.yaml: -------------------------------------------------------------------------------- 1 | web_profiler: 2 | toolbar: false 3 | intercept_redirects: false 4 | 5 | framework: 6 | profiler: { collect: false } 7 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test_cached/doctrine.yaml: -------------------------------------------------------------------------------- 1 | doctrine: 2 | orm: 3 | entity_managers: 4 | default: 5 | result_cache_driver: 6 | type: memcached 7 | host: localhost 8 | port: 11211 9 | query_cache_driver: 10 | type: memcached 11 | host: localhost 12 | port: 11211 13 | metadata_cache_driver: 14 | type: memcached 15 | host: localhost 16 | port: 11211 17 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test_cached/fidry_alice_data_fixtures.yaml: -------------------------------------------------------------------------------- 1 | fidry_alice_data_fixtures: 2 | default_purge_mode: no_purge -------------------------------------------------------------------------------- /tests/Application/config/packages/test_cached/framework.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | test: ~ 3 | session: 4 | storage_factory_id: session.storage.factory.mock_file 5 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test_cached/mailer.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | mailer: 3 | dsn: '%env(MAILER_DSN)%' 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test_cached/monolog.yaml: -------------------------------------------------------------------------------- 1 | monolog: 2 | handlers: 3 | main: 4 | type: stream 5 | path: "%kernel.logs_dir%/%kernel.environment%.log" 6 | level: error 7 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test_cached/security.yaml: -------------------------------------------------------------------------------- 1 | security: 2 | password_hashers: 3 | sha512: sha512 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test_cached/sylius_channel.yaml: -------------------------------------------------------------------------------- 1 | sylius_channel: 2 | debug: true 3 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test_cached/sylius_theme.yaml: -------------------------------------------------------------------------------- 1 | sylius_theme: 2 | sources: 3 | test: ~ 4 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test_cached/sylius_uploader.yaml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: "../test/sylius_uploader.yaml" } 3 | -------------------------------------------------------------------------------- /tests/Application/config/packages/test_cached/twig.yaml: -------------------------------------------------------------------------------- 1 | twig: 2 | strict_variables: true 3 | -------------------------------------------------------------------------------- /tests/Application/config/packages/translation.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | default_locale: '%locale%' 3 | translator: 4 | paths: 5 | - '%kernel.project_dir%/translations' 6 | fallbacks: 7 | - '%locale%' 8 | - 'en' 9 | -------------------------------------------------------------------------------- /tests/Application/config/packages/twig.yaml: -------------------------------------------------------------------------------- 1 | twig: 2 | paths: ['%kernel.project_dir%/templates'] 3 | debug: '%kernel.debug%' 4 | strict_variables: '%kernel.debug%' 5 | 6 | services: 7 | _defaults: 8 | public: false 9 | autowire: true 10 | autoconfigure: true 11 | 12 | Twig\Extra\Intl\IntlExtension: ~ 13 | -------------------------------------------------------------------------------- /tests/Application/config/packages/twig_extensions.yaml: -------------------------------------------------------------------------------- 1 | services: 2 | _defaults: 3 | public: false 4 | autowire: true 5 | autoconfigure: true 6 | 7 | # Uncomment any lines below to activate that Twig extension 8 | #Twig\Extensions\ArrayExtension: ~ 9 | #Twig\Extensions\DateExtension: ~ 10 | #Twig\Extensions\IntlExtension: ~ 11 | #Twig\Extensions\TextExtension: ~ 12 | -------------------------------------------------------------------------------- /tests/Application/config/packages/webpack_encore.yaml: -------------------------------------------------------------------------------- 1 | webpack_encore: 2 | output_path: '%kernel.project_dir%/public/build/default' 3 | builds: 4 | shop: '%kernel.project_dir%/public/build/shop' 5 | admin: '%kernel.project_dir%/public/build/admin' 6 | elasticsearch_shop: '%kernel.project_dir%/public/build/bitbag/elasticsearch/shop' 7 | elasticsearch_admin: '%kernel.project_dir%/public/build/bitbag/elasticsearch/admin' 8 | -------------------------------------------------------------------------------- /tests/Application/config/routes.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/tests/Application/config/routes.yaml -------------------------------------------------------------------------------- /tests/Application/config/routes/api_platform.yaml: -------------------------------------------------------------------------------- 1 | api_platform: 2 | resource: . 3 | type: api_platform 4 | prefix: /api 5 | -------------------------------------------------------------------------------- /tests/Application/config/routes/bitbag_sylius_elasticsearch_plugin.yaml: -------------------------------------------------------------------------------- 1 | bitbag_sylius_elasticsearch_plugin: 2 | resource: "@BitBagSyliusElasticsearchPlugin/config/routing.yml" 3 | -------------------------------------------------------------------------------- /tests/Application/config/routes/dev/twig.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/tests/Application/config/routes/dev/twig.yaml -------------------------------------------------------------------------------- /tests/Application/config/routes/dev/web_profiler.yaml: -------------------------------------------------------------------------------- 1 | _wdt: 2 | resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml" 3 | prefix: /_wdt 4 | 5 | _profiler: 6 | resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml" 7 | prefix: /_profiler 8 | -------------------------------------------------------------------------------- /tests/Application/config/routes/liip_imagine.yaml: -------------------------------------------------------------------------------- 1 | _liip_imagine: 2 | resource: "@LiipImagineBundle/Resources/config/routing.yaml" 3 | -------------------------------------------------------------------------------- /tests/Application/config/routes/sylius_admin.yaml: -------------------------------------------------------------------------------- 1 | sylius_admin: 2 | resource: "@SyliusAdminBundle/Resources/config/routing.yml" 3 | prefix: /admin 4 | -------------------------------------------------------------------------------- /tests/Application/config/routes/sylius_api.yaml: -------------------------------------------------------------------------------- 1 | sylius_api: 2 | resource: "@SyliusApiBundle/Resources/config/routing.yml" 3 | prefix: "%sylius.security.api_route%" 4 | -------------------------------------------------------------------------------- /tests/Application/config/routes/sylius_shop.yaml: -------------------------------------------------------------------------------- 1 | sylius_shop: 2 | resource: "@SyliusShopBundle/Resources/config/routing.yml" 3 | prefix: /{_locale} 4 | requirements: 5 | _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ 6 | 7 | sylius_shop_payum: 8 | resource: "@SyliusPayumBundle/Resources/config/routing/integrations/sylius_shop.yaml" 9 | 10 | sylius_shop_default_locale: 11 | path: / 12 | methods: [GET] 13 | defaults: 14 | _controller: sylius_shop.controller.locale_switch::switchAction 15 | -------------------------------------------------------------------------------- /tests/Application/config/routes/test/routing.yaml: -------------------------------------------------------------------------------- 1 | sylius_test_plugin_main: 2 | path: /test/main 3 | controller: FrameworkBundle:Template:template 4 | defaults: 5 | template: "@SyliusTestPlugin/main.html.twig" 6 | -------------------------------------------------------------------------------- /tests/Application/config/routes/test/sylius_test_plugin.yaml: -------------------------------------------------------------------------------- 1 | sylius_test_plugin_main: 2 | path: /test/main 3 | controller: FrameworkBundle:Template:template 4 | defaults: 5 | template: "@SyliusTestPlugin/main.html.twig" 6 | -------------------------------------------------------------------------------- /tests/Application/config/routes/test_cached/routing.yaml: -------------------------------------------------------------------------------- 1 | sylius_test_plugin_main: 2 | path: /test/main 3 | controller: FrameworkBundle:Template:template 4 | defaults: 5 | template: "@SyliusTestPlugin/main.html.twig" 6 | -------------------------------------------------------------------------------- /tests/Application/config/routes/test_cached/sylius_test_plugin.yaml: -------------------------------------------------------------------------------- 1 | sylius_test_plugin_main: 2 | path: /test/main 3 | controller: FrameworkBundle:Template:template 4 | defaults: 5 | template: "@SyliusTestPlugin/main.html.twig" 6 | -------------------------------------------------------------------------------- /tests/Application/config/services.yaml: -------------------------------------------------------------------------------- 1 | # Put parameters here that don't need to change on each machine where the app is deployed 2 | # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration 3 | parameters: 4 | locale: en_US 5 | bitbag_es_shop_price_facet_interval: 1000000 6 | 7 | services: 8 | bitbag_sylius_elasticsearch_plugin.facet.registry: 9 | class: BitBag\SyliusElasticsearchPlugin\Facet\Registry 10 | calls: 11 | - method: addFacet 12 | arguments: 13 | - price 14 | - '@bitbag_sylius_elasticsearch_plugin.facet.price' 15 | - method: addFacet 16 | arguments: 17 | - taxon 18 | - '@bitbag_sylius_elasticsearch_plugin.facet.taxon' 19 | -------------------------------------------------------------------------------- /tests/Application/config/services_test.yaml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: "../../Behat/Resources/services.xml" } 3 | - { resource: "../../../vendor/sylius/sylius/src/Sylius/Behat/Resources/config/services.xml" } 4 | 5 | # workaround needed for strange "test.client.history" problem 6 | # see https://github.com/FriendsOfBehat/SymfonyExtension/issues/88 7 | services: 8 | Symfony\Component\BrowserKit\AbstractBrowser: '@test.client' 9 | -------------------------------------------------------------------------------- /tests/Application/config/services_test_cached.yaml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: "services_test.yaml" } 3 | -------------------------------------------------------------------------------- /tests/Application/config/symfony/4.4/packages/framework.yaml: -------------------------------------------------------------------------------- 1 | framework: 2 | templating: { engines: ["twig"] } 3 | -------------------------------------------------------------------------------- /tests/Application/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "license": "UNLICENSED", 3 | "scripts": { 4 | "build": "encore dev", 5 | "build:prod": "encore production", 6 | "watch": "encore dev --watch" 7 | }, 8 | "dependencies": { 9 | "@sylius-ui/admin": "file:../../vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle", 10 | "@sylius-ui/shop": "file:../../vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle", 11 | "@symfony/ux-autocomplete": "file:../../vendor/symfony/ux-autocomplete/assets", 12 | "@symfony/ux-live-component": "file:../../vendor/symfony/ux-live-component/assets", 13 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 14 | "babel-preset-env": "^1.7.0" 15 | }, 16 | "devDependencies": { 17 | "@hotwired/stimulus": "^3.0.0", 18 | "@symfony/stimulus-bridge": "^3.2.0", 19 | "@symfony/webpack-encore": "^5.0.1", 20 | "tom-select": "^2.2.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Application/public/.htaccess: -------------------------------------------------------------------------------- 1 | DirectoryIndex app.php 2 | 3 | 4 | RewriteEngine On 5 | 6 | RewriteCond %{HTTP:Authorization} ^(.*) 7 | RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] 8 | 9 | RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ 10 | RewriteRule ^(.*) - [E=BASE:%1] 11 | 12 | RewriteCond %{ENV:REDIRECT_STATUS} ^$ 13 | RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L] 14 | 15 | RewriteCond %{REQUEST_FILENAME} -f 16 | RewriteRule .? - [L] 17 | 18 | RewriteRule .? %{ENV:BASE}/index.php [L] 19 | 20 | 21 | 22 | 23 | RedirectMatch 302 ^/$ /index.php/ 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/Application/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/tests/Application/public/favicon.ico -------------------------------------------------------------------------------- /tests/Application/public/index.php: -------------------------------------------------------------------------------- 1 | handle($request); 28 | $response->send(); 29 | $kernel->terminate($request, $response); 30 | -------------------------------------------------------------------------------- /tests/Application/public/robots.txt: -------------------------------------------------------------------------------- 1 | # www.robotstxt.org/ 2 | # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 3 | 4 | User-agent: * 5 | -------------------------------------------------------------------------------- /tests/Application/templates/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/tests/Application/templates/.gitignore -------------------------------------------------------------------------------- /tests/Application/templates/shop/javascripts.html.twig: -------------------------------------------------------------------------------- 1 | {{ encore_entry_script_tags('shop-entry', null, 'shop') }} 2 | {{ encore_entry_script_tags('bitbag-elasticsearch-shop', null, 'elasticsearch_shop') }} 3 | -------------------------------------------------------------------------------- /tests/Application/templates/shop/stylesheets.html.twig: -------------------------------------------------------------------------------- 1 | {{ encore_entry_link_tags('shop-entry', null, 'shop') }} 2 | {{ encore_entry_link_tags('bitbag-elasticsearch-shop', null, 'elasticsearch_shop') }} 3 | -------------------------------------------------------------------------------- /tests/Application/translations/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitBagCommerce/SyliusElasticsearchPlugin/a27b12eba93227d621276f9686dceb66291442a8/tests/Application/translations/.gitignore -------------------------------------------------------------------------------- /tests/Behat/Context/Setup/ElasticsearchContext.php: -------------------------------------------------------------------------------- 1 | populate->populateIndex(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/Behat/Context/Ui/Shop/HomepageContext.php: -------------------------------------------------------------------------------- 1 | homePage->open(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/Behat/Page/Shop/HomePage.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/Behat/Resources/services/contexts/api.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/Behat/Resources/services/contexts/ui.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/Behat/Resources/services/pages/shop/home_page.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/Behat/Resources/services/pages/shop/product.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/Behat/Resources/services/pages/shop/search.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/Behat/Resources/suites.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - suites/api/searching_products.yaml 3 | - suites/ui/filtering_products.yaml 4 | - suites/ui/site_wide_searching_products.yaml 5 | -------------------------------------------------------------------------------- /tests/Behat/Resources/suites/api/searching_products.yaml: -------------------------------------------------------------------------------- 1 | default: 2 | suites: 3 | api_searching_products: 4 | contexts: 5 | - sylius.behat.context.hook.doctrine_orm 6 | 7 | - sylius.behat.context.transform.channel 8 | - sylius.behat.context.transform.lexical 9 | - sylius.behat.context.transform.locale 10 | - sylius.behat.context.transform.product 11 | - sylius.behat.context.transform.shared_storage 12 | - sylius.behat.context.transform.taxon 13 | 14 | - sylius.behat.context.setup.channel 15 | - sylius.behat.context.setup.currency 16 | - sylius.behat.context.setup.locale 17 | - sylius.behat.context.setup.taxonomy 18 | 19 | - bitbag.sylius_elasticsearch_plugin.behat.context.setup.product 20 | - bitbag.sylius_elasticsearch_plugin.behat.context.setup.product_attribute 21 | - bitbag.sylius_elasticsearch_plugin.behat.context.setup.product_taxon 22 | - bitbag.sylius_elasticsearch_plugin.behat.context.setup.elasticsearch 23 | 24 | - bitbag.sylius_elasticsearch_plugin.behat.context.api.shop.product 25 | filters: 26 | tags: "@searching_products&&@api" 27 | -------------------------------------------------------------------------------- /tests/Behat/Resources/suites/ui/filtering_products.yaml: -------------------------------------------------------------------------------- 1 | default: 2 | suites: 3 | ui_filtering_products: 4 | contexts: 5 | - sylius.behat.context.hook.doctrine_orm 6 | 7 | - sylius.behat.context.transform.channel 8 | - sylius.behat.context.transform.lexical 9 | - sylius.behat.context.transform.locale 10 | - sylius.behat.context.transform.product 11 | - sylius.behat.context.transform.shared_storage 12 | - sylius.behat.context.transform.taxon 13 | 14 | - sylius.behat.context.setup.channel 15 | - sylius.behat.context.setup.currency 16 | - sylius.behat.context.setup.locale 17 | - sylius.behat.context.setup.taxonomy 18 | 19 | - bitbag.sylius_elasticsearch_plugin.behat.context.setup.product 20 | - bitbag.sylius_elasticsearch_plugin.behat.context.setup.product_attribute 21 | - bitbag.sylius_elasticsearch_plugin.behat.context.setup.product_taxon 22 | - bitbag.sylius_elasticsearch_plugin.behat.context.setup.elasticsearch 23 | 24 | - bitbag.sylius_elasticsearch_plugin.behat.context.ui.shop.product 25 | filters: 26 | tags: "@filtering_products&&@ui" 27 | -------------------------------------------------------------------------------- /tests/Behat/Resources/suites/ui/site_wide_searching_products.yaml: -------------------------------------------------------------------------------- 1 | default: 2 | suites: 3 | ui_site_wide_searching_products: 4 | contexts: 5 | - sylius.behat.context.hook.doctrine_orm 6 | 7 | - sylius.behat.context.transform.shared_storage 8 | - sylius.behat.context.transform.taxon 9 | - sylius.behat.context.transform.product 10 | - sylius.behat.context.transform.lexical 11 | - sylius.behat.context.transform.product_option 12 | 13 | - sylius.behat.context.setup.channel 14 | - sylius.behat.context.setup.taxonomy 15 | - sylius.behat.context.setup.product_taxon 16 | - sylius.behat.context.setup.product 17 | - sylius.behat.context.setup.product_attribute 18 | - sylius.behat.context.setup.product_option 19 | - bitbag.sylius_elasticsearch_plugin.behat.context.setup.product 20 | - bitbag.sylius_elasticsearch_plugin.behat.context.setup.elasticsearch 21 | 22 | - bitbag.sylius_elasticsearch_plugin.behat.context.ui.shop.search 23 | - bitbag.sylius_elasticsearch_plugin.behat.context.ui.shop.home_page 24 | filters: 25 | tags: "@site_wide_searching_products&&@ui" 26 | -------------------------------------------------------------------------------- /tests/PHPUnit/Integration/Api/DataFixtures/ORM/test_it_finds_products_by_name.yaml: -------------------------------------------------------------------------------- 1 | Sylius\Component\Core\Model\Channel: 2 | channel_web: 3 | code: 'WEB' 4 | name: 'Web Channel' 5 | hostname: 'localhost' 6 | description: 'Lorem ipsum' 7 | baseCurrency: '@currency_usd' 8 | defaultLocale: '@locale_en' 9 | locales: ['@locale_en'] 10 | color: 'black' 11 | enabled: true 12 | taxCalculationStrategy: 'order_items_based' 13 | 14 | Sylius\Component\Currency\Model\Currency: 15 | currency_usd: 16 | code: 'USD' 17 | 18 | Sylius\Component\Locale\Model\Locale: 19 | locale_en: 20 | code: 'en_US' 21 | 22 | Sylius\Component\Core\Model\Product: 23 | product_mug: 24 | code: 'MUG' 25 | channels: ['@channel_web'] 26 | currentLocale: 'en_US' 27 | translations: 28 | en_US: '@product_translation_mug' 29 | 30 | Sylius\Component\Core\Model\ProductTranslation: 31 | product_translation_mug: 32 | slug: 'mug' 33 | locale: 'en_US' 34 | name: 'Mug' 35 | description: '' 36 | translatable: '@product_mug' 37 | 38 | Sylius\Component\Core\Model\Taxon: 39 | mugs: 40 | code: "mugs" 41 | 42 | Sylius\Component\Core\Model\ProductTaxon: 43 | productTaxon1: 44 | product: "@product_mug" 45 | taxon: "@mugs" 46 | position: 0 47 | -------------------------------------------------------------------------------- /tests/PHPUnit/Integration/Api/Responses/Expected/test_it_finds_products_by_name.json: -------------------------------------------------------------------------------- 1 | { 2 | "items": [ 3 | { 4 | "productTaxons": [ 5 | "/api/v2/shop/product-taxons/@string@" 6 | ], 7 | "mainTaxon": null, 8 | "averageRating": "@integer@ || @float@", 9 | "images": [], 10 | "id": "@integer@", 11 | "code": "MUG", 12 | "variants": [], 13 | "options": [], 14 | "associations": [], 15 | "createdAt": "@string@", 16 | "updatedAt": "@string@", 17 | "shortDescription": null, 18 | "reviews": [], 19 | "name": "Mug", 20 | "description": "@string@", 21 | "slug": "mug", 22 | "defaultVariant": null 23 | } 24 | ], 25 | "facets": { 26 | "taxon": { 27 | "doc_count_error_upper_bound": 0, 28 | "sum_other_doc_count": 0, 29 | "buckets": [ 30 | { 31 | "key": "mugs", 32 | "doc_count": 1 33 | } 34 | ] 35 | } 36 | }, 37 | "pagination": { 38 | "current_page": 1, 39 | "has_previous_page": false, 40 | "has_next_page": false, 41 | "per_page": 9, 42 | "total_items": 1, 43 | "total_pages": 1 44 | } 45 | } -------------------------------------------------------------------------------- /tests/PHPUnit/Integration/Api/Responses/Expected/test_it_finds_products_by_name_and_facets.json: -------------------------------------------------------------------------------- 1 | { 2 | "items": [ 3 | { 4 | "productTaxons": [ 5 | "/api/v2/shop/product-taxons/@string@" 6 | ], 7 | "mainTaxon": null, 8 | "averageRating": 0, 9 | "images": [], 10 | "id": "@integer@", 11 | "code": "MUG", 12 | "variants": [], 13 | "options": [], 14 | "associations": [], 15 | "createdAt": "@string@", 16 | "updatedAt": "@string@", 17 | "shortDescription": null, 18 | "reviews": [], 19 | "name": "Mug", 20 | "description": "@string@", 21 | "slug": "mug", 22 | "defaultVariant": null 23 | } 24 | ], 25 | "facets": { 26 | "color": { 27 | "doc_count_error_upper_bound": 0, 28 | "sum_other_doc_count": 0, 29 | "buckets": [ 30 | { 31 | "key": "red", 32 | "doc_count": 1 33 | } 34 | ] 35 | }, 36 | "taxon": { 37 | "doc_count_error_upper_bound": 0, 38 | "sum_other_doc_count": 0, 39 | "buckets": [ 40 | { 41 | "key": "mugs", 42 | "doc_count": 1 43 | } 44 | ] 45 | } 46 | }, 47 | "pagination": { 48 | "current_page": 1, 49 | "has_previous_page": false, 50 | "has_next_page": false, 51 | "per_page": 9, 52 | "total_items": 1, 53 | "total_pages": 1 54 | } 55 | } -------------------------------------------------------------------------------- /tests/PHPUnit/Integration/DataFixtures/ORM/Repository/ProductAttributeValueRepositoryTest/test_product_attribute_repository.yaml: -------------------------------------------------------------------------------- 1 | Sylius\Component\Product\Model\ProductAttribute: 2 | product_attribute_brand: 3 | code: 't_shirt_brand' 4 | type: 'text' 5 | storage_type: 'text' 6 | position: 1 7 | translatable: 0 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/PHPUnit/Integration/DataFixtures/ORM/Repository/ProductAttributeValueRepositoryTest/test_product_attribute_value_repository.yaml: -------------------------------------------------------------------------------- 1 | Sylius\Component\Core\Model\Channel: 2 | channel_web: 3 | code: 'WEB' 4 | name: 'Web Channel' 5 | hostname: 'localhost' 6 | description: 'Lorem ipsum' 7 | baseCurrency: '@currency_usd' 8 | defaultLocale: '@locale_en' 9 | locales: ['@locale_en'] 10 | color: 'black' 11 | enabled: true 12 | taxCalculationStrategy: 'order_items_based' 13 | 14 | Sylius\Component\Currency\Model\Currency: 15 | currency_usd: 16 | code: 'USD' 17 | 18 | Sylius\Component\Locale\Model\Locale: 19 | locale_en: 20 | code: 'en_US' 21 | 22 | Sylius\Component\Core\Model\Product: 23 | product_mug: 24 | code: 'MUG' 25 | channels: ['@channel_web'] 26 | currentLocale: 'en_US' 27 | 28 | Sylius\Component\Product\Model\ProductAttribute: 29 | product_attribute_brand: 30 | code: 't_shirt_brand' 31 | type: 'text' 32 | storage_type: 'text' 33 | position: 1 34 | translatable: 0 35 | 36 | Sylius\Component\Product\Model\ProductAttributeValue: 37 | product_attribute_value_brand: 38 | product: '@product_mug' 39 | attribute: '@product_attribute_brand' 40 | locale_code: '@locale_en' 41 | value: 'You are breathtaking' 42 | 43 | Sylius\Component\Core\Model\Taxon: 44 | mugs: 45 | code: "mugs" 46 | 47 | Sylius\Component\Core\Model\ProductTaxon: 48 | productTaxon1: 49 | product: "@product_mug" 50 | taxon: "@mugs" 51 | position: 0 52 | 53 | -------------------------------------------------------------------------------- /tests/PHPUnit/Integration/IntegrationTestCase.php: -------------------------------------------------------------------------------- 1 | dataFixturesPath = __DIR__ . \DIRECTORY_SEPARATOR . 'DataFixtures' . \DIRECTORY_SEPARATOR . 'ORM'; 25 | $this->expectedResponsesPath = __DIR__ . \DIRECTORY_SEPARATOR . 'Responses' . \DIRECTORY_SEPARATOR . 'Expected'; 26 | } 27 | 28 | protected function setUp(): void 29 | { 30 | self::bootKernel(); 31 | } 32 | 33 | protected function tearDown(): void 34 | { 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /translations/messages.ar.yml: -------------------------------------------------------------------------------- 1 | bitbag_sylius_elasticsearch_plugin: 2 | ui: 3 | min_price: أدنى سعر 4 | max_price: أعلى سعر 5 | filter_results: فلترة النتائج 6 | filter: فلترة 7 | sort: ترتيب حسب 8 | bestsellers: الأفضل مبيعا 9 | newest: الأحدث 10 | oldest: الأقدم 11 | most_expensive: الأعلى سعرا 12 | cheapest: الأرخص 13 | per_page: على الصفحة 14 | -------------------------------------------------------------------------------- /translations/messages.cs.yml: -------------------------------------------------------------------------------- 1 | bitbag_sylius_elasticsearch_plugin: 2 | ui: 3 | min_price: Cena od 4 | max_price: Cena do 5 | filter_results: Filtrace 6 | filter: Filtrovat 7 | sort: Řazení 8 | bestsellers: Nejprodávanější 9 | newest: Nejnovější 10 | oldest: Nejstarší 11 | most_expensive: Nejdražší 12 | cheapest: Nejlevnější 13 | per_page: Na stránku 14 | -------------------------------------------------------------------------------- /translations/messages.en.yml: -------------------------------------------------------------------------------- 1 | bitbag_sylius_elasticsearch_plugin: 2 | ui: 3 | min_price: Min price 4 | max_price: Max price 5 | filter_results: Filter results 6 | filter: Filter 7 | sort: Sort by 8 | bestsellers: Bestsellers 9 | newest: Newest 10 | oldest: Oldest 11 | most_expensive: Most expensive 12 | cheapest: Cheapest 13 | per_page: Per page 14 | search_header: Search 15 | 16 | search_box: 17 | query: 18 | placeholder: Search for products... 19 | search_button: 20 | label: Search 21 | search_in_taxon: Search in this taxon 22 | 23 | facet: 24 | price: 25 | label: Price 26 | taxon: 27 | label: Taxon 28 | -------------------------------------------------------------------------------- /translations/messages.fr.yml: -------------------------------------------------------------------------------- 1 | bitbag_sylius_elasticsearch_plugin: 2 | ui: 3 | min_price: Prix min 4 | max_price: Prix max 5 | filter_results: Filtrer les résultats 6 | filter: Filtrer 7 | sort: Trier par 8 | bestsellers: Meilleures ventes 9 | newest: Plus récent en premier 10 | oldest: Plus ancien en premier 11 | most_expensive: Plus cher en premier 12 | cheapest: Moins cher en premier 13 | per_page: Nombre de résultats 14 | search_header: Recherche 15 | 16 | search_box: 17 | query: 18 | placeholder: Rechercher des produits... 19 | search_button: 20 | label: Rechercher 21 | 22 | facet: 23 | price: 24 | label: Prix 25 | taxon: 26 | label: Catégorie 27 | -------------------------------------------------------------------------------- /translations/messages.nl.yml: -------------------------------------------------------------------------------- 1 | bitbag_sylius_elasticsearch_plugin: 2 | ui: 3 | min_price: Minimale prijs 4 | max_price: Maximale prijs 5 | filter_results: Filter resultaten 6 | filter: Filter 7 | sort: Sorteer op 8 | bestsellers: Bestsellers 9 | newest: Nieuwste 10 | oldest: Oudste 11 | most_expensive: Duurste 12 | cheapest: Goedkoopste 13 | per_page: Per pagina 14 | search_header: Zoeken 15 | 16 | search_box: 17 | query: 18 | placeholder: Zoeken naar producten... 19 | search_button: 20 | label: Zoeken 21 | 22 | facet: 23 | price: 24 | label: Prijs 25 | taxon: 26 | label: Categorie 27 | -------------------------------------------------------------------------------- /translations/validators.en.yml: -------------------------------------------------------------------------------- 1 | bitbag_sylius_elasticsearch_plugin: 2 | min_price_numeric: Min price must be a valid price 3 | max_price_numeric: Max price must be a valid price 4 | min_price_positive_or_zero: Min price cannot be negative 5 | max_price_positive_or_zero: Max price cannot be negative 6 | price_value_too_large: Provided price value is too large 7 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const Encore = require('@symfony/webpack-encore'); 3 | const pluginName = 'elasticsearch'; 4 | 5 | const getConfig = (pluginName, type) => { 6 | Encore.reset(); 7 | 8 | Encore 9 | .setOutputPath(`public/build/bitbag/${pluginName}/${type}/`) 10 | .setPublicPath(`/build/bitbag/${pluginName}/${type}/`) 11 | .addEntry(`bitbag-${pluginName}-${type}`, path.resolve(__dirname, `./assets/${type}/entry.js`)) 12 | .disableSingleRuntimeChunk() 13 | .cleanupOutputBeforeBuild() 14 | .enableSourceMaps(!Encore.isProduction()) 15 | .enableSassLoader(); 16 | 17 | const config = Encore.getWebpackConfig(); 18 | config.name = `bitbag-${pluginName}-${type}`; 19 | 20 | return config; 21 | } 22 | 23 | Encore 24 | .setOutputPath(`src/Resources/public/`) 25 | .setPublicPath(`/public/`) 26 | .addEntry(`bitbag-${pluginName}-shop`, path.resolve(__dirname, `./src/assets/shop/entry.js`)) 27 | .addEntry(`bitbag-${pluginName}-admin`, path.resolve(__dirname, `./src/assets/admin/entry.js`)) 28 | .cleanupOutputBeforeBuild() 29 | .disableSingleRuntimeChunk() 30 | .enableSassLoader(); 31 | 32 | const distConfig = Encore.getWebpackConfig(); 33 | distConfig.name = `bitbag-plugin-dist`; 34 | 35 | Encore.reset(); 36 | 37 | const shopConfig = getConfig(pluginName, 'shop') 38 | const adminConfig = getConfig(pluginName, 'admin') 39 | 40 | module.exports = [shopConfig, adminConfig, distConfig]; 41 | --------------------------------------------------------------------------------