Category Filters feature integration
Edit on GitHubPrerequisites
Prepare your project to work with Category Filters:
-
Require the Category Filters modules in your composer by running the following commands:
composer require spryker/product-category-filter
composer require spryker/product-category-filter-collector
composer require spryker/product-category-filter-gui
-
Install the new database:
vendor/bin/console propel:diff
Propel generates a migration file with the changes.
- Apply the database changes:
vendor/bin/console propel:migrate
- Generate ORM models:
vendor/bin/console propel:model:build
This command generates some new classes in your project under the \Orm\Zed\ProductCategoryFilter\Persistence namespace
.
Verification
Make sure that they extend the base classes from the Spryker core—for example:
\Orm\Zed\ProductCategoryFilter\Persistence\SpyProductCategoryFilter
extends\Spryker\Zed\ProductCategoryFilter\Persistence\Propel\AbstractSpyProductCategoryFilter
\Orm\Zed\ProductReview\Persistence\SpyProductCategoryFilterQuery
extends\Spryker\Zed\ProductCategoryFilter\Persistence\Propel\AbstractSpyProductCategoryFilterQuery
- Generate the new transfer objects:
vendor/bin/console transfer:generate
- Activate the product category filters collector. For this, add
ProductCategoryFilterCollectorPlugin
to the Storage Collector plugin stack.
Example: collector plugin list extension
<?php
namespace Pyz\Zed\Collector;
use Spryker\Zed\Collector\CollectorDependencyProvider as SprykerCollectorDependencyProvider;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\ProductReviewCollector\Communication\Plugin\ProductReviewCollectorSearchPlugin;
use Spryker\Zed\ProductReviewCollector\Communication\Plugin\ProductAbstractReviewCollectorStoragePlugin;
// ...
class CollectorDependencyProvider extends SprykerCollectorDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\Kernel\Container
*/
public function provideBusinessLayerDependencies(Container $container)
{
// ...
$container[static::STORAGE_PLUGINS] = function (Container $container) {
return [
// ...
ProductCategoryFilterConfig::RESOURCE_TYPE_PRODUCT_CATEGORY_FILTER => new ProductCategoryFilterCollectorPlugin(),
];
};
// ...
}
}
- Make sure the new Zed user interface assets are built:
npm run zed
- Update Zed’s navigation cache to show the new items for the Product Category Filter management user interface:
vendor/bin/console application:build-navigation-cache
You can use the Zed UI of Category Filters to reorder, remove or add search filters to specific categories, and the collectors also can push those category settings to storage.
For the frontend implementation example and general idea, see our Demoshop implementation on GitHub.
Update filters for a category
- To use the setup category filter,
CatalogController::indexAction
needs to callProductCategoryFilterClient::updateFacetsByCategory
—for example, it might look like this:
<?php
/**
* @method \Pyz\Yves\Catalog\CatalogFactory getFactory()
* @method \Spryker\Client\Catalog\CatalogClientInterface getClient()
*/
class CatalogController extends AbstractController
{
const STORAGE_CACHE_STRATEGY = StorageConstants::STORAGE_CACHE_STRATEGY_INCREMENTAL;
/**
* @param array $categoryNode
* @param \Symfony\Component\HttpFoundation\Request $request
*
* @return array|\Symfony\Component\HttpFoundation\Response
*/
public function indexAction(array $categoryNode, Request $request)
{
$searchString = $request->query->get('q', '');
$parameters = $request->query->all();
$parameters[PageIndexMap::CATEGORY] = $categoryNode['node_id'];
$searchResults = $this
->getClient()
->catalogSearch($searchString, $parameters);
$currentLocale = $this
->getFactory()
->getLocaleClient()
->getCurrentLocale();
$productCategoryFilterClient = $this->getFactory()->getProductCategoryFilterClient();
$searchResults[FacetResultFormatterPlugin::NAME] = $productCategoryFilterClient
->updateFacetsByCategory(
$searchResults[FacetResultFormatterPlugin::NAME],
$productCategoryFilterClient->getProductCategoryFiltersForCategoryByLocale($parameters[PageIndexMap::CATEGORY], $currentLocale)
); //This line here is the one that updates the facets with the category filters.
$pageTitle = ($categoryNode['meta_title']) ?: $categoryNode['name'];
$metaAttributes = [
'idCategory' => $parameters['category'],
'category' => $categoryNode,
'page_title' => $pageTitle,
'page_description' => $categoryNode['meta_description'],
'page_keywords' => $categoryNode['meta_keywords'],
'searchString' => $searchString,
];
$searchResults = array_merge($searchResults, $metaAttributes);
return $this->envelopeResult($searchResults, $categoryNode['node_id']);
}
}
- Add
ProductCategoryFilterClient
toCatalogFactory
:
<?php
namespace Pyz\Yves\Catalog;
class CatalogFactory extends AbstractFactory
{
/**
* @return \Spryker\Client\ProductCategoryFilter\ProductCategoryFilterClientInterface
*/
public function getProductCategoryFilterClient()
{
return $this->getProvidedDependency(CatalogDependencyProvider::CLIENT_PRODUCT_CATEGORY_FILTER);
}
}
- Add an additional dependency to
CatalogDependencyProvider
to look like this:
<?php
namespace Pyz\Yves\Catalog;
class CatalogDependencyProvider extends AbstractBundleDependencyProvider
{
const CLIENT_PRODUCT_CATEGORY_FILTER = 'CLIENT_PRODUCT_CATEGORY_FILTER';
/**
* @param \Spryker\Yves\Kernel\Container $container
*
* @return \Spryker\Yves\Kernel\Container
*/
public function provideDependencies(Container $container)
{
$container = $this->addProductCategoryFilterClient($container);
return $container;
}
/**
* @param \Spryker\Yves\Kernel\Container $container
*
* @return \Spryker\Yves\Kernel\Container
*/
protected function addProductCategoryFilterClient(Container $container)
{
$container[static::CLIENT_PRODUCT_CATEGORY_FILTER] = function (Container $container) {
return $container->getLocator()->productCategoryFilter()->client();
};
return $container;
}
}
Thank you!
For submitting the form