Product Rating and Reviews feature integration
Edit on GitHubPrerequisites
To prepare your project to work with Product Reviews:
- Require the Product Review modules in your composer by running
composer require spryker/product-review
composer require spryker/product-review-collector
composer require spryker/product-review-gui
- Install the new database tables by running
vendor/bin/console propel:diff
. Propel should generate a migration file with the changes. - Run
vendor/bin/console propel:migrate
to apply the database changes. - Generate ORM models by running
vendor/bin/console propel:model:build
. This command will generate some new classes in your project under\Orm\Zed\ProductReview\Persistence
namespace. It is important to make sure that they extend the base classes from the Spryker core, e.g.:\Orm\Zed\ProductReview\Persistence\SpyProductReview
extends\Spryker\Zed\ProductReview\Persistence\Propel\AbstractSpyProductReview
\Orm\Zed\ProductReview\Persistence\SpyProductReviewQuery
extends\Spryker\Zed\ProductReview\Persistence\Propel\AbstractSpyProductReviewQuery
- Run
vendor/bin/console transfer:generate
to generate the new transfer objects. - Activate the product review collectors by adding the
ProductReviewCollectorSearchPlugin
and theProductAbstractReviewCollectorStoragePlugin
to the Storage and Search 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::SEARCH_PLUGINS] = function (Container $container) {
return [
// ...
ProductReviewConfig::RESOURCE_TYPE_PRODUCT_REVIEW => new ProductReviewCollectorSearchPlugin(),
];
};
$container[static::STORAGE_PLUGINS] = function (Container $container) {
return [
// ...
ProductReviewConfig::RESOURCE_TYPE_PRODUCT_ABSTRACT_REVIEW => new ProductAbstractReviewCollectorStoragePlugin(),
];
};
// ...
}
}
- Run
vendor/bin/console setup:search
to set up Search before you run Search collectors. - Make sure the new Zed user interface assets are built by running
npm run zed
(or antelope build zed for older versions). - Update Zed’s navigation cache to show the new items for the Product Review management user interface by running
vendor/bin/console application:build-navigation-cache
.
You should now be able to use the Zed API of Product Reviews to approve, reject and delete reviews, and the collectors should also be able to push approved reviews and ratings into Storage and Search. Check out our Demoshop implementation for frontend implementation example and idea.
Usage in Yves
Submitting a Product Review
To store an already validated product review, populate a \Generated\Shared\Transfer\ProductReviewTransfer
transfer object and send it to Zed by calling the \Spryker\Client\ProductReview\ProductReviewClientInterface::submitCustomerReview
method.
This action will create a new pending product review in your persistent storage. The saved product review will be exported to Search and Storage after it was approved on Zed UI.
Make sure that the provided rating value does not exceed the configured maximum rating limit.
Example of how to store a validated customer review:
<?php
/**
* @method \Pyz\Yves\ProductReview\ProductReviewFactory getFactory()
*/
class SubmitController extends Pyz\Yves\Application\Controller\AbstractController
{
/**
* @param \Symfony\Component\HttpFoundation\Request $request
*/
public function submitAction(Request $request)
{
$customerReference = $this->getFactory()->getCustomerClient()->getCustomer()->getCustomerReference();
$this->getFactory()->getProductReviewClient()->submitCustomerReview(
(new ProductReviewRequestTransfer())
->setCustomerReference($customerReference)
->setLocaleName($this->getLocale())
->setIdProductAbstract($request->attributes->get('idProductAbstract'))
->setSummary($request->attributes->get('summary'))
->setDescription($request->attributes->get('description'))
->setRating($request->attributes->get('rating'))
->setNickname($request->attributes->get('nickname'))
);
}
}
Displaying an Average Rating
To display the average rating stored in Storage, you will need to use spyProductAbstractReview
and spyProductAbstractReviewMaximumRating
twig extensions shipped by ProductReview
module.
-
spyProductAbstractReview
twig extension takes product abstract ID as first argument and injects the correspondingProductAbstractReviewTransfer
transfer object into the twig template provided as the second argument. -
spyProductAbstractReviewMaximumRating
twig extension allows you to retrieve the configured maximum rating on demand.
To register these plugins, you need to add ProductAbstractReviewTwigServiceProvider
service provider to your\Pyz\Yves\Application\YvesBootstrap.php
.
Example of how to register twig extensions:
<?php
namespace Pyz\Yves\Application;
use Spryker\Yves\ProductReview\Plugin\Provider\ProductAbstractReviewTwigServiceProvider;
class YvesBootstrap
{
/**
* @return void
*/
protected function registerServiceProviders()
{
// ...
$this->application->register(new ProductAbstractReviewTwigServiceProvider());
}
}
Now you will be able to call the registered spyProductAbstractReview
and spyProductAbstractReviewMaximumRating
twig extensions in your twig templates.
Below is the example spyProductAbstractReview
call.
@ProductReview/index/index.twig
:
<div>Product name: {{product.name}}</div>
{{ spyProductAbstractReview(product.idProductAbstract, '@ProductReview/partials/average-rating.twig') }}
The spyProductAbstractReview
twig extension will render the template provided as a second argument and inject the productAbstractReviewTransfer variable.
Below is the example average-rating.twig implementation.
@ProductReview/partials/average-rating.twig:
{% block content %}
{% if productAbstractReviewTransfer %}
Average product rating is {{ productAbstractReviewTransfer.averageRating }} out of {{ spyProductAbstractReviewMaximumRating() }}
{% endif %}
{% endblock %}
Displaying Reviews and Rating Summary
To display previously posted and already approved reviews from Search, you will need to call \Spryker\Client\ProductReview\ProductReviewClientInterface::findProductReviewsInSearch
method.
To alter the retrieved number of product reviews per page, change the Client configuration.
Example of product review retrieval:
namespace Pyz\Yves\ProductReview\Controller;
use Generated\Shared\Transfer\ProductReviewSearchRequestTransfer;
use Pyz\Yves\Application\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
/**
* @method \Spryker\Client\ProductReview\ProductReviewClientInterface getClient()
*/
class IndexController extends AbstractController
{
/**
* @param \Symfony\Component\HttpFoundation\Request $request
*
* @return array
*/
public function indexAction(Request $request)
{
$productReviews = $this->getClient()->findProductReviewsInSearch(
(new ProductReviewSearchRequestTransfer())
->setIdProductAbstract($request->attributes->get('idProductAbstract'));
->setRequestParams($request->query->all())
);
return [
'productReviews' => $productReviews['productReviews'],
'pagination' => $productReviews['pagination'],
'ratingAggregation' => $productReviews['ratingAggregation'],
];
}
}
Thank you!
For submitting the form