Skip to content

Commit 9365b57

Browse files
committed
Adding Product and Customer Reviews GraphQl support
1 parent 985c679 commit 9365b57

27 files changed

+1911
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Review\Model\Review;
9+
10+
use Magento\Review\Model\ResourceModel\Rating\Option\Vote\Collection as OptionVoteCollection;
11+
use Magento\Review\Model\ResourceModel\Rating\Option\Vote\CollectionFactory as OptionVoteCollectionFactory;
12+
use Magento\Review\Model\ResourceModel\Review\Product\Collection;
13+
14+
/**
15+
* The model that adds the rating votes to reviews
16+
*/
17+
class AddRatingVotesToCustomerReviews
18+
{
19+
/**
20+
* @var RatingOptionCollectionFactory
21+
*/
22+
private $ratingOptionCollectionFactory;
23+
24+
/**
25+
* @param OptionVoteCollectionFactory $ratingOptionCollectionFactory
26+
*/
27+
public function __construct(OptionVoteCollectionFactory $ratingOptionCollectionFactory)
28+
{
29+
$this->ratingOptionCollectionFactory = $ratingOptionCollectionFactory;
30+
}
31+
32+
/**
33+
* Add rating votes to customer reviews
34+
*
35+
* @param Collection $collection
36+
*/
37+
public function execute(Collection $collection): void
38+
{
39+
$connection = $collection->getConnection();
40+
41+
foreach ($collection->getItems() as &$item) {
42+
/** @var OptionVoteCollection $votesCollection */
43+
$votesCollection = $this->ratingOptionCollectionFactory->create();
44+
45+
$votesCollection->addFieldToFilter('main_table.review_id', $item->getData('review_id'));
46+
$votesCollection->getSelect()
47+
->join(
48+
['rating' => $connection->getTableName('rating')],
49+
'rating.rating_id = main_table.rating_id',
50+
['rating_code']
51+
);
52+
$item->setRatingVotes($votesCollection);
53+
}
54+
}
55+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Review\Service;
9+
10+
/**
11+
* Get review average rating
12+
*/
13+
class GetReviewAverageRatingService
14+
{
15+
/**
16+
* Get average rating per review
17+
*
18+
* @param array $ratingVotes
19+
*
20+
* @return float
21+
*/
22+
public function execute(array $ratingVotes): float
23+
{
24+
$averageRating = 0;
25+
26+
foreach ($ratingVotes as $ratingVote) {
27+
$averageRating += (int) $ratingVote->getData('value');
28+
}
29+
30+
return $averageRating > 0 ? (float) number_format($averageRating / count($ratingVotes), 2) : 0;
31+
}
32+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ReviewGraphQl\Mapper;
9+
10+
use Magento\Catalog\Model\Product;
11+
use Magento\Review\Model\Review;
12+
13+
/**
14+
* Converts the review data from review object to an associative array
15+
*/
16+
class ReviewDataMapper
17+
{
18+
/**
19+
* Mapping the review data
20+
*
21+
* @param Review|Product $review
22+
*
23+
* @return array
24+
*/
25+
public function map($review): array
26+
{
27+
return [
28+
'summary' => $review->getData('title'),
29+
'text' => $review->getData('detail'),
30+
'nickname' => $review->getData('nickname'),
31+
'created_at' => $review->getData('created_at'),
32+
'rating_votes' => $review->getData('rating_votes'),
33+
'sku' => $review->getSku()
34+
];
35+
}
36+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ReviewGraphQl\Model\DataProvider;
9+
10+
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
11+
use Magento\Review\Model\ResourceModel\Review\Collection as ReviewCollection;
12+
use Magento\Review\Model\ResourceModel\Review\Product\Collection as ProductCollection;
13+
use Magento\ReviewGraphQl\Mapper\ReviewDataMapper;
14+
15+
/**
16+
* Provides aggregated reviews result
17+
*
18+
* The following class prepares the GraphQl endpoints' result for Customer and Product reviews
19+
*/
20+
class AggregatedReviewsDataProvider
21+
{
22+
/**
23+
* @var ReviewDataMapper
24+
*/
25+
private $reviewDataMapper;
26+
27+
/**
28+
* @param ReviewDataMapper $reviewDataMapper
29+
*/
30+
public function __construct(ReviewDataMapper $reviewDataMapper)
31+
{
32+
$this->reviewDataMapper = $reviewDataMapper;
33+
}
34+
35+
/**
36+
* Get reviews result
37+
*
38+
* @param ProductCollection|ReviewCollection $reviewsCollection
39+
*
40+
* @return array
41+
*/
42+
public function getData($reviewsCollection): array
43+
{
44+
if ($reviewsCollection->getPageSize()) {
45+
$maxPages = ceil($reviewsCollection->getSize() / $reviewsCollection->getPageSize());
46+
} else {
47+
$maxPages = 0;
48+
}
49+
50+
$currentPage = $reviewsCollection->getCurPage();
51+
if ($reviewsCollection->getCurPage() > $maxPages && $reviewsCollection->getSize() > 0) {
52+
$currentPage = new GraphQlInputException(
53+
__(
54+
'currentPage value %1 specified is greater than the number of pages available.',
55+
[$maxPages]
56+
)
57+
);
58+
}
59+
60+
$items = [];
61+
foreach ($reviewsCollection->getItems() as $item) {
62+
$items[] = $this->reviewDataMapper->map($item);
63+
}
64+
65+
return [
66+
'total_count' => $reviewsCollection->getSize(),
67+
'items' => $items,
68+
'page_info' => [
69+
'page_size' => $reviewsCollection->getPageSize(),
70+
'current_page' => $currentPage,
71+
'total_pages' => $maxPages
72+
]
73+
];
74+
}
75+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ReviewGraphQl\Model\DataProvider;
9+
10+
use Magento\Review\Model\ResourceModel\Review\Product\Collection as ProductReviewsCollection;
11+
use Magento\Review\Model\ResourceModel\Review\Product\CollectionFactory;
12+
use Magento\Review\Model\Review\AddRatingVotesToCustomerReviews;
13+
14+
/**
15+
* Provides customer reviews
16+
*/
17+
class CustomerReviewsDataProvider
18+
{
19+
/**
20+
* @var CollectionFactory
21+
*/
22+
private $collectionFactory;
23+
24+
/**
25+
* @var AddRatingVotesToCustomerReviews
26+
*/
27+
private $addRatingVotesToCustomerReviews;
28+
29+
/**
30+
* @param CollectionFactory $collectionFactory
31+
* @param AddRatingVotesToCustomerReviews $addRatingVotesToCustomerReviews
32+
*/
33+
public function __construct(
34+
CollectionFactory $collectionFactory,
35+
AddRatingVotesToCustomerReviews $addRatingVotesToCustomerReviews
36+
) {
37+
$this->collectionFactory = $collectionFactory;
38+
$this->addRatingVotesToCustomerReviews = $addRatingVotesToCustomerReviews;
39+
}
40+
41+
/**
42+
* Get customer reviews
43+
*
44+
* @param int $customerId
45+
* @param int $currentPage
46+
* @param int $pageSize
47+
*
48+
* @return ProductReviewsCollection
49+
*/
50+
public function getData(int $customerId, int $currentPage, int $pageSize): ProductReviewsCollection
51+
{
52+
/** @var ProductReviewsCollection $reviewsCollection */
53+
$reviewsCollection = $this->collectionFactory->create();
54+
$reviewsCollection->addCustomerFilter($customerId)
55+
->setPageSize($pageSize)
56+
->setCurPage($currentPage)
57+
->setDateOrder();
58+
$this->addRatingVotesToCustomerReviews->execute($reviewsCollection);
59+
60+
return $reviewsCollection;
61+
}
62+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ReviewGraphQl\Model\DataProvider;
9+
10+
use Magento\Review\Model\ResourceModel\Review\Collection;
11+
use Magento\Review\Model\ResourceModel\Review\CollectionFactory;
12+
use Magento\Review\Model\Review;
13+
14+
/**
15+
* Provides product reviews
16+
*/
17+
class ProductReviewsDataProvider
18+
{
19+
/**
20+
* @var CollectionFactory
21+
*/
22+
private $collectionFactory;
23+
24+
/**
25+
* @param CollectionFactory $collectionFactory
26+
*/
27+
public function __construct(
28+
CollectionFactory $collectionFactory
29+
) {
30+
$this->collectionFactory = $collectionFactory;
31+
}
32+
33+
/**
34+
* Get product reviews
35+
*
36+
* @param int $productId
37+
* @param int $currentPage
38+
* @param int $pageSize
39+
*
40+
* @return Collection
41+
*/
42+
public function getData(int $productId, int $currentPage, int $pageSize): Collection
43+
{
44+
/** @var Collection $reviewsCollection */
45+
$reviewsCollection = $this->collectionFactory->create()
46+
->addStatusFilter(Review::STATUS_APPROVED)
47+
->addEntityFilter(Review::ENTITY_PRODUCT_CODE, $productId)
48+
->setPageSize($pageSize)
49+
->setCurPage($currentPage)
50+
->setDateOrder();
51+
$reviewsCollection->getSelect()->join(
52+
['cpe' => $reviewsCollection->getTable('catalog_product_entity')],
53+
'cpe.entity_id = main_table.entity_pk_value',
54+
['sku']
55+
);
56+
$reviewsCollection->addRateVotes();
57+
58+
return $reviewsCollection;
59+
}
60+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\ReviewGraphQl\Model\DataProvider;
9+
10+
/**
11+
* Provides rating votes
12+
*/
13+
class ReviewRatingsDataProvider
14+
{
15+
/**
16+
* Providing rating votes
17+
*
18+
* @param array $ratingVotes
19+
*
20+
* @return array
21+
*/
22+
public function getData(array $ratingVotes): array
23+
{
24+
$data = [];
25+
26+
foreach ($ratingVotes as $ratingVote) {
27+
$data[] = [
28+
'name' => $ratingVote->getData('rating_code'),
29+
'value' => $ratingVote->getData('value')
30+
];
31+
}
32+
33+
return $data;
34+
}
35+
}

0 commit comments

Comments
 (0)