spryker-eco / algolia
Algolia module
Installs: 232
Dependents: 0
Suggesters: 1
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/spryker-eco/algolia
Requires
- php: >=8.3
- ext-curl: *
- ext-intl: *
- ext-json: *
- algolia/algoliasearch-client-php: ^3.4.2
- spryker-shop/traceable-event-widget: ^1.1.0
- spryker/cms: ^7.18.0
- spryker/customer: ^7.70.0
- spryker/event-behavior: ^1.32.0
- spryker/http: ^1.15.0
- spryker/kernel: ^3.76.0
- spryker/locale: ^4.12.0
- spryker/log: ^3.18.0
- spryker/product: ^6.53.0
- spryker/product-category: ^4.28.1
- spryker/product-image: ^3.20.0
- spryker/publisher-extension: ^1.0.0
- spryker/search-extension: ^1.4.0
- spryker/search-http: ^0.5.9
- spryker/store: ^1.30.0
- spryker/symfony: ^3.19.2
Requires (Dev)
- phpstan/phpstan: ^2.1
- psr/http-message: ^1.1.0 || ^2.0.0
- spryker/code-sniffer: ^0.17.30
- spryker/guzzle: *
- spryker/propel: *
- spryker/testify: ^3.62.0
Suggests
- spryker/merchant-product: Optional for merchants in search.
- spryker/merchant-product-offer: Optional for offers in search.
- spryker/price-product: Optional for Price search.
- spryker/product-bundle-storage: Optional for product Bundle in search.
- spryker/product-label: Optional for product Label in search.
- spryker/product-review: Optional for product rating search.
This package is auto-updated.
Last update: 2026-02-15 17:26:53 UTC
README
The Algolia module provides seamless integration between Spryker Commerce OS and Algolia search service, enabling real-time synchronization of products and CMS pages to Algolia indices for fast, relevant search experiences.
Features
- 🔄 Real-time synchronization of products and CMS pages to Algolia
- 🎯 Event-driven architecture using Spryker's Publisher module
- 🌍 Multi-locale and multi-store support
- 📦 Batch export capabilities for initial data sync
- 🔍 Search API integration for frontend and backend
- ⚙️ Configurable event subscriptions per entity type
- 🏗️ Modular design with optional module support
- 🔌 Custom entity index mapping for searching any custom entity in Algolia
Table of Contents
- Installation
- Real-time Synchronization
- Full Indexing
- Custom Entity Index Mapping
- Configuration
- Migration from ACP Algolia App
- Troubleshooting
- Development
Installation
composer require spryker-eco/algolia
Configure Algolia credentials in your config files:
// config/Shared/config_default.php or config_local.php use SprykerEco\Shared\Algolia\AlgoliaConstants; $config[AlgoliaConstants::IS_ACTIVE] = true; $config[AlgoliaConstants::APPLICATION_ID] = getenv('ALGOLIA_APPLICATION_ID'); $config[AlgoliaConstants::ADMIN_API_KEY] = getenv('ALGOLIA_ADMIN_API_KEY'); $config[AlgoliaConstants::SEARCH_ONLY_API_KEY] = getenv('ALGOLIA_SEARCH_ONLY_API_KEY'); $config[AlgoliaConstants::TENANT_IDENTIFIER] = 'john'; // Add if you use one Algolia account for multiple environments, default is "production".
Step 1: Enable Console Command
File: src/Pyz/Zed/Console/ConsoleDependencyProvider.php
<?php namespace Pyz\Zed\Console; use Spryker\Zed\Console\ConsoleDependencyProvider as SprykerConsoleDependencyProvider; use SprykerEco\Zed\Algolia\Communication\Console\AlgoliaEntityExportConsole; class ConsoleDependencyProvider extends SprykerConsoleDependencyProvider { /** * @param \Spryker\Zed\Kernel\Container $container * * @return array<\Symfony\Component\Console\Command\Command> */ protected function getConsoleCommands(Container $container): array { $commands = [ // ... existing commands // Add Algolia export command new AlgoliaEntityExportConsole(), ]; return $commands; } }
Step 2: Configure Entity Exporter Plugins
File: src/Pyz/Zed/Algolia/AlgoliaDependencyProvider.php
<?php namespace Pyz\Zed\Algolia; use SprykerEco\Zed\Algolia\AlgoliaDependencyProvider as SprykerEcoAlgoliaDependencyProvider; use SprykerEco\Zed\Algolia\Communication\Plugin\Algolia\CmsPageAlgoliaEntityExporterPlugin; use SprykerEco\Zed\Algolia\Communication\Plugin\Algolia\ProductAlgoliaEntityExporterPlugin; class AlgoliaDependencyProvider extends SprykerEcoAlgoliaDependencyProvider { /** * @return array<\SprykerEco\Zed\Algolia\Dependency\Plugin\AlgoliaEntityExporterPluginInterface> */ protected function getAlgoliaEntityExporterPlugins(): array { return [ new ProductAlgoliaEntityExporterPlugin(), new CmsPageAlgoliaEntityExporterPlugin(), // Add more entity exporters here ]; } }
Step 3: Configure Search Adapter Plugin
File: src/Pyz/Client/Search/SearchDependencyProvider.php
<?php namespace Pyz\Client\Search; use Spryker\Client\Search\SearchDependencyProvider as SprykerSearchDependencyProvider; use SprykerEco\Client\Algolia\Plugin\Search\AlgoliaSearchAdapterPlugin; class SearchDependencyProvider extends SprykerSearchDependencyProvider { /** * @return array<\Spryker\Client\SearchExtension\Dependency\Plugin\SearchAdapterPluginInterface> */ protected function getClientAdapterPlugins(): array { return [ new AlgoliaSearchAdapterPlugin(), // ... other search adapters ]; } }
Step 4: Configure Catalog Search Query Plugins
Note: Also requires
\Pyz\Shared\Algolia\AlgoliaConfig::isSearchInFrontendEnabledForProducts()to be set totrue.
Note 2: Integration heavily depends on SearchHttp module plugins, so they have to be also enabled in
src/Pyz/Client/Catalog/CatalogDependencyProvider.php, see the integration guide.
File: src/Pyz/Client/Catalog/CatalogDependencyProvider.php
<?php namespace Pyz\Client\Catalog; use Spryker\Client\Catalog\CatalogDependencyProvider as SprykerCatalogDependencyProvider; use SprykerEco\Client\Algolia\Plugin\Search\AlgoliaSearchQueryPlugin; use SprykerEco\Client\Algolia\Plugin\Search\AlgoliaSuggestionSearchQueryPlugin; use SprykerEco\Client\Algolia\Plugin\Search\AlgoliaProductConcreteSearchQueryPlugin; class CatalogDependencyProvider extends SprykerCatalogDependencyProvider { /** * @return array<\Spryker\Client\SearchExtension\Dependency\Plugin\QueryInterface> */ protected function createCatalogSearchQueryPluginVariants(): array { return [ new AlgoliaSearchQueryPlugin(), ]; } /** * @return array<\Spryker\Client\SearchExtension\Dependency\Plugin\QueryInterface> */ protected function createSuggestionQueryPluginVariants(): array { return [ new AlgoliaSuggestionSearchQueryPlugin(), ]; } /** * @return array<\Spryker\Client\SearchExtension\Dependency\Plugin\QueryInterface> */ protected function createProductConcreteCatalogSearchQueryPluginVariants(): array { return [ new AlgoliaProductConcreteSearchQueryPlugin(), ]; } }
Step 5: Configure CMS Page Search Query Plugin (Optional)
Note: Also requires
\Pyz\Shared\Algolia\AlgoliaConfig::isSearchInFrontendEnabledForCmsPages()to be set totrue.
Note 2: Integration heavily depends on SearchHttp module plugins, so they have to be also enabled in
src/Pyz/Client/SearchHttp/SearchHttpDependencyProvider.phpandsrc/Pyz/Client/CmsPageSearch/CmsPageSearchDependencyProvider.php, see the integration guide.
File: src/Pyz/Client/CmsPageSearch/CmsPageSearchDependencyProvider.php
<?php namespace Pyz\Client\CmsPageSearch; use Generated\Shared\Transfer\SearchContextTransfer; use Spryker\Client\CmsPageSearch\CmsPageSearchConfig; use Spryker\Client\CmsPageSearch\CmsPageSearchDependencyProvider as SprykerCmsPageSearchDependencyProvider; use SprykerEco\Client\Algolia\Plugin\Search\AlgoliaSearchQueryPlugin; class CmsPageSearchDependencyProvider extends SprykerCmsPageSearchDependencyProvider { /** * @return array<\Spryker\Client\SearchExtension\Dependency\Plugin\QueryInterface> */ protected function getCmsPageSearchQueryPlugins(): array { return [ new AlgoliaSearchQueryPlugin( (new SearchContextTransfer()) ->setSourceIdentifier(CmsPageSearchConfig::SOURCE_IDENTIFIER_CMS_PAGE), ), // ... other search query plugins ]; } }
Step 6: Generate Transfers
vendor/bin/console transfer:generate
Step 7: Verify Installation
# List available commands (should show algolia:entity-export) vendor/bin/console | grep algolia vendor/bin/console algolia:entity-export
Step 8: Send data to Algolia
vendor/bin/console algolia:entity-export --all
# Or export specific entity types
vendor/bin/console algolia:entity-export product
vendor/bin/console algolia:entity-export cms-page
See Full Indexing section for more details and scheduling options.
See Real-time Synchronization section for real-time updates.
Step 9: Verify data in the Algolia Dashboard
- Login to Algolia
- Check created indexes and data inside (Search section).
- Try searches from the Algolia Dashboard.
- Tune index settings (facets, searchable attributes) as needed.
Step 10: Configure Real-time Synchronization
Complete Integration Example:
<?php namespace Pyz\Zed\Publisher; use Spryker\Zed\Publisher\PublisherDependencyProvider as SprykerPublisherDependencyProvider; use SprykerEco\Zed\Algolia\Communication\Plugin\Publisher\Product\AlgoliaProductAbstractPublisherPlugin; use SprykerEco\Zed\Algolia\Communication\Plugin\Publisher\Product\AlgoliaProductConcretePublisherPlugin; use SprykerEco\Zed\Algolia\Communication\Plugin\Publisher\Product\AlgoliaProductConcreteDeletePublisherPlugin; use SprykerEco\Zed\Algolia\Communication\Plugin\Publisher\CmsPage\AlgoliaCmsPagePublisherPlugin; use SprykerEco\Zed\Algolia\Communication\Plugin\Publisher\CmsPage\AlgoliaCmsPageVersionPublisherPlugin; use SprykerEco\Zed\Algolia\Communication\Plugin\Publisher\CmsPage\AlgoliaCmsPageDeletePublisherPlugin; class PublisherDependencyProvider extends SprykerPublisherDependencyProvider { protected function getPublisherPlugins(): array { return [ // Algolia product publishers new AlgoliaProductConcretePublisherPlugin(), new AlgoliaProductAbstractPublisherPlugin(), new AlgoliaProductConcreteDeletePublisherPlugin(), // Algolia CMS page publishers new AlgoliaCmsPagePublisherPlugin(), new AlgoliaCmsPageVersionPublisherPlugin(), new AlgoliaCmsPageDeletePublisherPlugin(), ]; } }
See Real-time Synchronization section for details on each plugin and their subscribed events.
Step 11: Enable Search in Frontend & API
WARNING: Please make sure you have data in the Algolia indices before enabling search in frontend, otherwise search will return no results.
Enable product and/or CMS page search in the frontend for Algolia integration at the project level.
File: src/Pyz/Client/Algolia/AlgoliaConfig.php
<?php namespace Pyz\Client\Algolia; use SprykerEco\Client\Algolia\AlgoliaConfig as SprykerEcoAlgoliaConfig; class AlgoliaConfig extends SprykerEcoAlgoliaConfig { /** * Enable product search in frontend. */ public function isSearchInFrontendEnabledForProducts(): bool { return true; } /** * Enable CMS page search in frontend. */ public function isSearchInFrontendEnabledForCmsPages(): bool { return true; } }
Real-time Synchronization
Product Publisher Plugins
Located in: SprykerEco\Zed\Algolia\Communication\Plugin\Publisher\Product\
1. AlgoliaProductConcretePublisherPlugin
Purpose: Publishes product concrete (variant) data to Algolia when products are created or updated.
Default Subscribed Events:
- Product creation/update events
- Product localized attributes changes
- Product images changes
- Product bundles changes (if ProductBundleStorage exists)
- Product prices changes (if PriceProduct exists)
- Product search data changes (if ProductSearch exists)
Behavior:
- Publishes or updates product concrete data in Algolia indices upon relevant events.
- Handles multi-store and multi-locale data.
2. AlgoliaProductAbstractPublisherPlugin
Purpose: Publishes all concrete products of a product abstract when abstract-level data changes.
Default Subscribed Events:
- Product abstract updates
- Category assignments
- Product labels
- Reviews
- Images
- Price changes (if PriceProduct exists and enabled in the configuration)
Behavior:
- Triggers re-indexing of all related concrete products in Algolia when abstract-level data changes.
3. AlgoliaProductConcreteDeletePublisherPlugin
Purpose: Removes deleted products from Algolia indices.
Default Subscribed Events:
- PRODUCT_CONCRETE_UNPUBLISH
- ENTITY_SPY_PRODUCT_DELETE
Behavior:
- Removes product concrete data from Algolia indices when products are deleted or unpublished.
CMS Page Publisher Plugins
Located in: SprykerEco\Zed\Algolia\Communication\Plugin\Publisher\CmsPage\
1. AlgoliaCmsPagePublisherPlugin
Purpose: Publishes CMS page data to Algolia when pages are created or updated.
Default Subscribed Events:
- ENTITY_SPY_CMS_PAGE_UPDATE
Behavior:
- Fetches full CMS page data including latest version
- Checks if page is active AND searchable before publishing
- Extracts locale-specific flattened CMS content
- Sends complete page data to Algolia for indexing
- Removes pages from all relevant indices if page is inactive or not searchable
2. AlgoliaCmsPageVersionPublisherPlugin
Purpose: Publishes CMS pages when new versions are created or published.
Default Subscribed Events:
- CMS_VERSION_PUBLISH
- ENTITY_SPY_CMS_VERSION_CREATE
Behavior:
- Maps CMS version IDs to CMS page IDs
- Fetches CMS page and version data
- Extracts full page content with locale-specific data
- Publishes to Algolia with version metadata
Full Indexing
Usage Examples
# Export all products to Algolia console algolia:entity:export product # Export all CMS pages console algolia:entity:export cms-page --store=DE # Export for specific store console algolia:entity:export product --locale=en_US # Export with custom chunk size console algolia:entity:export product --chunk-size=200
Schedule Automatic Exports (Recommended)
For periodic full re-indexing, add a cron job to export entities to Algolia on a scheduled basis.
File: config/Zed/cronjobs/jenkins.php
/* Algolia - Weekly full export */ $jobs[] = [ 'name' => 'algolia-export-products', 'command' => $logger . '$PHP_BIN vendor/bin/console algolia:entity:export product', 'schedule' => '0 2 * * 0', 'enable' => true, ]; $jobs[] = [ 'name' => 'algolia-export-cms-pages', 'command' => $logger . '$PHP_BIN vendor/bin/console algolia:entity:export cms-page', 'schedule' => '30 2 * * 0', 'enable' => true, ];
Schedule explanation:
0 2 * * 0- Runs at 2:00 AM every Sunday (weekly)30 2 * * 0- Runs at 2:30 AM every Sunday (weekly)
Note: These cron jobs complement the real-time publisher plugins. The publishers handle incremental updates, while the cron jobs ensure full data consistency by performing periodic complete exports.
Custom Entity Index Mapping
The Algolia module supports searching custom entities that are already indexed in Algolia but are not natively supported by the module (like products or CMS pages). This feature allows you to integrate any custom entity search without creating new plugins or modules.
When to Use
Use entity-to-index mapping when you:
- Have custom entities (e.g., documents, manufacturers, locations) already indexed in Algolia
- Want to search these entities from your Spryker storefront
- Don't want to create custom publisher plugins for simple read-only search
Quick Setup
Step 1: Configure the mapping in your shared config:
<?php namespace Pyz\Shared\Algolia; use SprykerEco\Shared\Algolia\AlgoliaConfig as SprykerEcoAlgoliaConfig; class AlgoliaConfig extends SprykerEcoAlgoliaConfig { public function getEntityToIndexMappings(): array { return [ [ 'sourceIdentifier' => 'document', 'store' => 'DE', 'locales' => ['de_DE'], 'indexName' => 'documents_de', ], [ 'sourceIdentifier' => 'manufacturer', 'store' => '*', // All stores 'locales' => ['*'], // All locales 'indexName' => 'manufacturers', ], ]; } }
Step 2: Create a search query plugin:
<?php namespace Pyz\Client\YourModule\Plugin\Search; use Generated\Shared\Transfer\SearchContextTransfer; use Spryker\Client\Kernel\AbstractPlugin; use Spryker\Client\SearchExtension\Dependency\Plugin\QueryInterface; /** * @method \Pyz\Client\YourModule\YourModuleFactory getFactory() */ class DocumentSearchQueryPlugin extends AbstractPlugin implements QueryInterface { protected const SOURCE_IDENTIFIER = 'document'; protected ?SearchContextTransfer $searchContextTransfer = null; public function getSearchQuery() { // Your query logic } public function getSearchContext(): SearchContextTransfer { return $this->searchContextTransfer ?? (new SearchContextTransfer()) ->setSourceIdentifier(static::SOURCE_IDENTIFIER); } public function setSearchContext(SearchContextTransfer $searchContextTransfer): void { $this->searchContextTransfer = $searchContextTransfer; } }
Step 3: Use the plugin in your dependency provider and execute search.
For a complete implementation guide with examples, see Custom Entity Index Mapping Guide.
Configuration
Available Configuration Methods
Product Events:
getProductConcreteSubscribedEvents()- Product variant eventsgetProductAbstractSubscribedEvents()- Product abstract eventsgetProductConcreteUnpublishSubscribedEvents()- Delete events
CMS Page Events:
getCmsPageUpdateSubscribedEvents()- Page update eventsgetCmsPageVersionPublishSubscribedEvents()- Version publish events
Search:
isSearchInFrontendEnabledForProducts()- Enable product search in frontendisSearchInFrontendEnabledForCmsPages()- Enable CMS page search in frontend
Insights & Analytics & Personalization:
getIsPersonalizationEnabled()- Enable/disable Algolia Personalization for search. This feature requires a premium Algolia plan.getProjectMappingFacets()- Facet names mapping for Algolia Insights event tracking (via TraceableEventWidget).
Default Event Subscriptions
All publisher plugins get their subscribed events from AlgoliaConfig. The config automatically includes events from optional modules if they exist:
For Products:
- All product abstract and product concrete events
- ProductBundle - Bundle events (if module exists)
- PriceProduct - Price events (if module exists)
- ProductLabel - Label events (if module exists)
- ProductReview - Review events (if module exists)
For CMS Pages:
- CMS - All CMS page and version events
Customizing Event Subscriptions
Extend AlgoliaConfig in your project to customize events:
<?php namespace Pyz\Zed\Algolia; use SprykerEco\Zed\Algolia\AlgoliaConfig as SprykerEcoAlgoliaConfig; class AlgoliaConfig extends SprykerEcoAlgoliaConfig { public function getProductConcreteSubscribedEvents(): array { // Completely override events return [ 'Product.product_concrete.publish', 'Entity.spy_product.update', ]; } public function getCmsPageUpdateSubscribedEvents(): array { // Extend parent events $events = parent::getCmsPageUpdateSubscribedEvents(); $events[] = 'YourCustom.custom_event'; return $events; } public function getDefaultExportChunkSize(): int { return 500; // Custom chunk size for exports } }
Architecture
Data Flow
Spryker Events (Back Office/API changes/Data Import)
↓
Publisher Module (Queue-based processing)
↓
Algolia Publisher Plugins
├── Product Publishers
└── CMS Page Publishers
↓
AlgoliaFacade → Mappers → Indexers → API Client
↓
Algolia Search Service
Event Consolidation
Products:
- Concrete events: Direct changes to variants
- Abstract events: Changes affecting all variants
- The abstract publisher fetches all active concrete products
CMS Pages:
- Page update events: Direct entity changes
- Version publish events: New version creation
- Delete events: Page removal (unpublish)
- Both update and version plugins ensure pages stay current
Troubleshooting
No entity types available
Problem: "No entity exporters are registered"
Solution:
- Ensure plugins are registered in
AlgoliaDependencyProvider::getAlgoliaEntityExporterPlugins() - Check the dependency provider is in
Pyznamespace if extended - Clear cache:
console cache:empty-all
Transfer not found
Problem: Class 'Generated\Shared\Transfer\AlgoliaExportCriteriaTransfer' not found
Solution:
console transfer:generate
Events not triggering
Problem: Changes not appearing in Algolia
Solution:
- Check
AlgoliaConfig::getIsActive()returnstrue - Verify publisher plugins are registered in
PublisherDependencyProvider - Check queue workers are running:
console queue:task:start publish
- Debug publishing with Xdebug
docker/sdk console -x queue:task:start publishor using logs.
Search requests are failing
Problem: Search queries return errors or no results
Solution:
- Verify Algolia credentials in config are correct
- Ensure indices exist in Algolia dashboard
- Disable personalization
getIsPersonalizationEnabled()if you use not premium plan.
Migration from ACP Algolia App
If migrating from MessageBroker-based Algolia ACP App:
Note: The logic of data synchronization remains the same, so if you don't want to re-synchronize all data to Algolia, just use TENANT_IDENTIFIER the same as ACP tenant ID:
$config[AlgoliaConstants::TENANT_IDENTIFIER] = 'tenant-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx';
Step 1: Remove Old Plugins
Remove from src/Pyz/Zed/Publisher/PublisherDependencyProvider.php
// - CmsPageVersionPublishedMessageBrokerPublisherPlugin // - CmsPageUpdateMessageBrokerPublisherPlugin // - ProductAbstractUpdatedMessageBrokerPublisherPlugin // - ProductConcreteCreatedMessageBrokerPublisherPlugin // - ProductConcreteDeletedMessageBrokerPublisherPlugin // - ProductConcreteExportedMessageBrokerPublisherPlugin // - ProductConcreteUpdatedMessageBrokerPublisherPlugin
Remove from src/Pyz/Zed/MessageBroker/MessageBrokerDependencyProvider.php
// - SearchEndpointMessageHandlerPlugin // - ProductExportMessageHandlerPlugin // - CmsPageMessageHandlerPlugin
Update in src/Pyz/Client/Search/SearchDependencyProvider.php
-
Replace
SearchHttpSearchAdapterPluginwithAlgoliaSearchAdapterPlugin -
Remove:
// - SearchHttpSearchContextExpanderPlugin
Update in src/Pyz/Client/Catalog/CatalogDependencyProvider.php
Replace them SearchHttp plugins with Algolia equivalents:
- Replace
SearchHttpQueryPluginwithAlgoliaSearchQueryPlugin - Replace
SuggestionSearchHttpQueryPluginwithAlgoliaSuggestionSearchQueryPlugin - Replace
ProductConcreteSearchHttpQueryPluginwithAlgoliaProductConcreteSearchQueryPlugin
Update in src/Pyz/Client/CmsPageSearch/CmsPageSearchDependencyProvider.php
- Replace
SearchHttpQueryPluginwithAlgoliaSearchQueryPlugin
Step 2: Add New Algolia Plugins and Configuration
Follow all integration steps from the Installation section.
Step 3: Verify
- No data migration needed - data structure remains the same
- Do full re-index using console command (see Full Indexing) section)
- Configure schedule for periodic exports if needed (see Schedule Automatic Exports section)
- Test with products update in Back Office
- Test with a CMS page update in Back Office
- Check Algolia dashboard for indexed content
Benefits of Migration
- ✅ Direct integration (no MessageBroker overhead)
- ✅ Simpler architecture
- ✅ Better performance
- ✅ Batch indexing support
- ✅ Configuration and extensibility
Performance Considerations
Products
- Published asynchronously via queue system
- Multiple events for same product are deduplicated
- Events from optional modules only registered if installed
- Use
AlgoliaConfigto limit events if needed
CMS Pages
- Published asynchronously via queue system
- Only active AND searchable pages indexed
- Not searchable or inactive pages removed from indices
General
- All plugins check
AlgoliaConfig::getIsActive()before subscribing - If Algolia disabled, no events processed
- Initial export uses configurable batch sizes
Support
For issues or questions:
- Check Spryker documentation
- Check Spryker ACP Algolia app documentation
- Review Algolia documentation
- Contact Spryker support
Development
To check/fix code style and run static analysis, use:
composer cs-fix # can be used standalone composer phpstan # only works together with Spryker project (uses autoloader from it)
for test execution check details in tests/README.md file.
License
This module is licensed under the same license as Spryker Commerce OS.