-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Adding Product Reviews GraphQl support #27882
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
magento-engcom-team
merged 26 commits into
magento:2.4-develop
from
eduard13:feature/review-graphql-261
Jul 15, 2020
Merged
Changes from 17 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
9365b57
Adding Product and Customer Reviews GraphQl support
eduard13 ddf7d53
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 51e2fbc
Small refactoring to re-implement the customer reviews
eduard13 0564f78
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 1d75c53
Small improvements
eduard13 e21d3a8
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 dd796f3
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 1b7bade
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 9b8912e
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 20dfcc6
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 5809bee
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 4fedd42
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 64f9f00
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 5a4b007
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 3592cf9
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 7089708
Merge branch '2.4-develop' into feature/review-graphql-261
avattam06 017da27
Updating schema description
eduard13 a020625
Adding reviews config checking
eduard13 0111b2d
Adding return types
eduard13 f168ca6
Small improvements
eduard13 f443741
Merge branch '2.4-develop' into feature/review-graphql-261
dthampy 11c7fd4
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 c9184f6
Merge branch '2.4-develop' into feature/review-graphql-261
eduard13 b974b48
Adding rollback fixtures and providing small adjustments
eduard13 de8598c
Updating WebAPI tests
eduard13 9230db6
Merge branch '2.4-develop' into feature/review-graphql-261
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
37 changes: 37 additions & 0 deletions
37
app/code/Magento/ReviewGraphQl/Mapper/ReviewDataMapper.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\ReviewGraphQl\Mapper; | ||
|
||
use Magento\Catalog\Model\Product; | ||
use Magento\Review\Model\Review; | ||
|
||
/** | ||
* Converts the review data from review object to an associative array | ||
*/ | ||
class ReviewDataMapper | ||
{ | ||
/** | ||
* Mapping the review data | ||
* | ||
* @param Review $review | ||
* | ||
* @return array | ||
*/ | ||
public function map(Review $review): array | ||
{ | ||
return [ | ||
'summary' => $review->getData('title'), | ||
'text' => $review->getData('detail'), | ||
'nickname' => $review->getData('nickname'), | ||
'created_at' => $review->getData('created_at'), | ||
'rating_votes' => $review->getData('rating_votes'), | ||
'sku' => $review->getSku(), | ||
'model' => $review | ||
]; | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
app/code/Magento/ReviewGraphQl/Model/DataProvider/AggregatedReviewsDataProvider.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\ReviewGraphQl\Model\DataProvider; | ||
|
||
use Magento\Framework\GraphQl\Exception\GraphQlInputException; | ||
use Magento\Review\Model\ResourceModel\Review\Collection as ReviewCollection; | ||
use Magento\Review\Model\ResourceModel\Review\Product\Collection as ProductCollection; | ||
use Magento\ReviewGraphQl\Mapper\ReviewDataMapper; | ||
|
||
/** | ||
* Provides aggregated reviews result | ||
* | ||
* The following class prepares the GraphQl endpoints' result for Customer and Product reviews | ||
*/ | ||
class AggregatedReviewsDataProvider | ||
{ | ||
/** | ||
* @var ReviewDataMapper | ||
*/ | ||
private $reviewDataMapper; | ||
|
||
/** | ||
* @param ReviewDataMapper $reviewDataMapper | ||
*/ | ||
public function __construct(ReviewDataMapper $reviewDataMapper) | ||
{ | ||
$this->reviewDataMapper = $reviewDataMapper; | ||
} | ||
|
||
/** | ||
* Get reviews result | ||
* | ||
* @param ProductCollection|ReviewCollection $reviewsCollection | ||
* | ||
* @return array | ||
*/ | ||
public function getData($reviewsCollection): array | ||
{ | ||
if ($reviewsCollection->getPageSize()) { | ||
$maxPages = ceil($reviewsCollection->getSize() / $reviewsCollection->getPageSize()); | ||
} else { | ||
$maxPages = 0; | ||
} | ||
|
||
$currentPage = $reviewsCollection->getCurPage(); | ||
if ($reviewsCollection->getCurPage() > $maxPages && $reviewsCollection->getSize() > 0) { | ||
$currentPage = new GraphQlInputException( | ||
__( | ||
'currentPage value %1 specified is greater than the number of pages available.', | ||
[$maxPages] | ||
) | ||
); | ||
} | ||
|
||
$items = []; | ||
foreach ($reviewsCollection->getItems() as $item) { | ||
$items[] = $this->reviewDataMapper->map($item); | ||
} | ||
|
||
return [ | ||
'total_count' => $reviewsCollection->getSize(), | ||
'items' => $items, | ||
'page_info' => [ | ||
'page_size' => $reviewsCollection->getPageSize(), | ||
'current_page' => $currentPage, | ||
'total_pages' => $maxPages | ||
] | ||
]; | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
app/code/Magento/ReviewGraphQl/Model/DataProvider/CustomerReviewsDataProvider.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\ReviewGraphQl\Model\DataProvider; | ||
|
||
use Magento\Review\Model\ResourceModel\Review\Collection as ReviewsCollection; | ||
use Magento\Review\Model\ResourceModel\Review\CollectionFactory as ReviewsCollectionFactory; | ||
use Magento\Review\Model\Review; | ||
|
||
/** | ||
* Provides customer reviews | ||
*/ | ||
class CustomerReviewsDataProvider | ||
{ | ||
/** | ||
* @var ReviewsCollectionFactory | ||
*/ | ||
private $collectionFactory; | ||
|
||
/** | ||
* @param ReviewsCollectionFactory $collectionFactory | ||
*/ | ||
public function __construct( | ||
ReviewsCollectionFactory $collectionFactory | ||
) { | ||
$this->collectionFactory = $collectionFactory; | ||
} | ||
|
||
/** | ||
* Get customer reviews | ||
* | ||
* @param int $customerId | ||
* @param int $currentPage | ||
* @param int $pageSize | ||
* | ||
* @return ReviewsCollection | ||
*/ | ||
public function getData(int $customerId, int $currentPage, int $pageSize): ReviewsCollection | ||
{ | ||
/** @var ReviewsCollection $reviewsCollection */ | ||
$reviewsCollection = $this->collectionFactory->create(); | ||
$reviewsCollection->addStatusFilter(Review::STATUS_APPROVED) | ||
->addCustomerFilter($customerId) | ||
->setPageSize($pageSize) | ||
->setCurPage($currentPage) | ||
->setDateOrder(); | ||
$reviewsCollection->getSelect()->join( | ||
['cpe' => $reviewsCollection->getTable('catalog_product_entity')], | ||
'cpe.entity_id = main_table.entity_pk_value', | ||
['sku'] | ||
); | ||
$reviewsCollection->addRateVotes(); | ||
|
||
return $reviewsCollection; | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
app/code/Magento/ReviewGraphQl/Model/DataProvider/ProductReviewsDataProvider.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\ReviewGraphQl\Model\DataProvider; | ||
|
||
use Magento\Review\Model\ResourceModel\Review\Collection; | ||
use Magento\Review\Model\ResourceModel\Review\CollectionFactory; | ||
use Magento\Review\Model\Review; | ||
|
||
/** | ||
* Provides product reviews | ||
*/ | ||
class ProductReviewsDataProvider | ||
{ | ||
/** | ||
* @var CollectionFactory | ||
*/ | ||
private $collectionFactory; | ||
|
||
/** | ||
* @param CollectionFactory $collectionFactory | ||
*/ | ||
public function __construct( | ||
CollectionFactory $collectionFactory | ||
) { | ||
$this->collectionFactory = $collectionFactory; | ||
} | ||
|
||
/** | ||
* Get product reviews | ||
* | ||
* @param int $productId | ||
* @param int $currentPage | ||
* @param int $pageSize | ||
* | ||
* @return Collection | ||
*/ | ||
public function getData(int $productId, int $currentPage, int $pageSize): Collection | ||
{ | ||
/** @var Collection $reviewsCollection */ | ||
$reviewsCollection = $this->collectionFactory->create() | ||
->addStatusFilter(Review::STATUS_APPROVED) | ||
->addEntityFilter(Review::ENTITY_PRODUCT_CODE, $productId) | ||
->setPageSize($pageSize) | ||
->setCurPage($currentPage) | ||
->setDateOrder(); | ||
$reviewsCollection->getSelect()->join( | ||
['cpe' => $reviewsCollection->getTable('catalog_product_entity')], | ||
'cpe.entity_id = main_table.entity_pk_value', | ||
['sku'] | ||
); | ||
$reviewsCollection->addRateVotes(); | ||
|
||
return $reviewsCollection; | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
app/code/Magento/ReviewGraphQl/Model/DataProvider/ReviewRatingsDataProvider.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\ReviewGraphQl\Model\DataProvider; | ||
|
||
use Magento\Review\Model\ResourceModel\Rating\Option\Vote\Collection as VoteCollection; | ||
use Magento\Review\Model\ResourceModel\Rating\Option\Vote\CollectionFactory as VoteCollectionFactory; | ||
|
||
/** | ||
* Provides rating votes | ||
*/ | ||
class ReviewRatingsDataProvider | ||
{ | ||
/** | ||
* @var VoteCollectionFactory | ||
*/ | ||
private $voteCollectionFactory; | ||
|
||
/** | ||
* @param VoteCollectionFactory $voteCollectionFactory | ||
*/ | ||
public function __construct(VoteCollectionFactory $voteCollectionFactory) | ||
{ | ||
$this->voteCollectionFactory = $voteCollectionFactory; | ||
} | ||
|
||
/** | ||
* Providing rating votes | ||
* | ||
* @param int $reviewId | ||
* | ||
* @return array | ||
*/ | ||
public function getData(int $reviewId): array | ||
{ | ||
/** @var VoteCollection $ratingVotes */ | ||
$ratingVotes = $this->voteCollectionFactory->create(); | ||
$ratingVotes->setReviewFilter($reviewId); | ||
$ratingVotes->addRatingInfo(); | ||
|
||
$data = []; | ||
|
||
foreach ($ratingVotes->getItems() as $ratingVote) { | ||
$data[] = [ | ||
'name' => $ratingVote->getData('rating_code'), | ||
'value' => $ratingVote->getData('value') | ||
]; | ||
} | ||
|
||
return $data; | ||
} | ||
} |
105 changes: 105 additions & 0 deletions
105
app/code/Magento/ReviewGraphQl/Model/Resolver/CreateProductReview.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\ReviewGraphQl\Model\Resolver; | ||
|
||
use Magento\Framework\GraphQl\Config\Element\Field; | ||
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; | ||
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; | ||
use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; | ||
use Magento\Framework\GraphQl\Query\Resolver\Value; | ||
use Magento\Framework\GraphQl\Query\ResolverInterface; | ||
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; | ||
use Magento\Review\Helper\Data as ReviewHelper; | ||
use Magento\ReviewGraphQl\Mapper\ReviewDataMapper; | ||
use Magento\ReviewGraphQl\Model\Review\AddReviewToProduct; | ||
use Magento\Store\Api\Data\StoreInterface; | ||
|
||
/** | ||
* Create product review resolver | ||
*/ | ||
class CreateProductReview implements ResolverInterface | ||
{ | ||
/** | ||
* @var ReviewHelper | ||
*/ | ||
private $reviewHelper; | ||
|
||
/** | ||
* @var AddReviewToProduct | ||
*/ | ||
private $addReviewToProduct; | ||
|
||
/** | ||
* @var ReviewDataMapper | ||
*/ | ||
private $reviewDataMapper; | ||
|
||
/** | ||
* @param AddReviewToProduct $addReviewToProduct | ||
* @param ReviewDataMapper $reviewDataMapper | ||
* @param ReviewHelper $reviewHelper | ||
*/ | ||
public function __construct( | ||
AddReviewToProduct $addReviewToProduct, | ||
ReviewDataMapper $reviewDataMapper, | ||
ReviewHelper $reviewHelper | ||
) { | ||
|
||
$this->addReviewToProduct = $addReviewToProduct; | ||
$this->reviewDataMapper = $reviewDataMapper; | ||
$this->reviewHelper = $reviewHelper; | ||
} | ||
|
||
/** | ||
* Resolve product review ratings | ||
* | ||
* @param Field $field | ||
* @param ContextInterface $context | ||
* @param ResolveInfo $info | ||
* @param array|null $value | ||
* @param array|null $args | ||
* | ||
* @return array[]|Value|mixed | ||
* | ||
eduard13 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* @throws GraphQlAuthorizationException | ||
* @throws GraphQlNoSuchEntityException | ||
* | ||
* @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||
*/ | ||
public function resolve( | ||
Field $field, | ||
$context, | ||
ResolveInfo $info, | ||
array $value = null, | ||
array $args = null | ||
) { | ||
$input = $args['input']; | ||
$customerId = null; | ||
|
||
if (false !== $context->getExtensionAttributes()->getIsCustomer()) { | ||
$customerId = (int) $context->getUserId(); | ||
} | ||
|
||
if (!$customerId && !$this->reviewHelper->getIsGuestAllowToWrite()) { | ||
throw new GraphQlAuthorizationException(__('Guest customers aren\'t allowed to add product reviews.')); | ||
} | ||
|
||
$sku = $input['sku']; | ||
$ratings = $input['ratings']; | ||
$data = [ | ||
'nickname' => $input['nickname'], | ||
'title' => $input['summary'], | ||
'detail' => $input['text'], | ||
]; | ||
/** @var StoreInterface $store */ | ||
$store = $context->getExtensionAttributes()->getStore(); | ||
$review = $this->addReviewToProduct->execute($data, $ratings, $sku, $customerId, (int) $store->getId()); | ||
|
||
return ['review' => $this->reviewDataMapper->map($review)]; | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @eduard13. very nice PR! I just have a couple of comments.
is rating_votes being used anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, looks like after refactoring the code, I've missed to remove this one.
Thank you for pointing up.
Will wait for the feedback regarding the other points and will make all the needed adjustments at once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this one.