Skip to content

Commit d73c173

Browse files
committed
Merge remote-tracking branch 'origin/MC-36149' into 2.4-develop-pr120
2 parents a38744a + 5311f1e commit d73c173

File tree

4 files changed

+270
-19
lines changed

4 files changed

+270
-19
lines changed

app/code/Magento/Review/Block/Product/ReviewRenderer.php

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
<?php
22
/**
3-
* Review renderer
4-
*
53
* Copyright © Magento, Inc. All rights reserved.
64
* See COPYING.txt for license details.
75
*/
@@ -11,13 +9,21 @@
119
use Magento\Catalog\Block\Product\ReviewRendererInterface;
1210
use Magento\Catalog\Model\Product;
1311
use Magento\Framework\App\ObjectManager;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Exception\NoSuchEntityException;
14+
use Magento\Framework\View\Element\Template;
15+
use Magento\Framework\View\Element\Template\Context;
16+
use Magento\Review\Model\AppendSummaryDataFactory;
17+
use Magento\Review\Model\Review;
18+
use Magento\Review\Model\ReviewFactory;
1419
use Magento\Review\Model\ReviewSummaryFactory;
1520
use Magento\Review\Observer\PredispatchReviewObserver;
21+
use Magento\Store\Model\ScopeInterface;
1622

1723
/**
18-
* Class ReviewRenderer
24+
* Review renderer
1925
*/
20-
class ReviewRenderer extends \Magento\Framework\View\Element\Template implements ReviewRendererInterface
26+
class ReviewRenderer extends Template implements ReviewRendererInterface
2127
{
2228
/**
2329
* Array of available template name
@@ -32,7 +38,7 @@ class ReviewRenderer extends \Magento\Framework\View\Element\Template implements
3238
/**
3339
* Review model factory
3440
*
35-
* @var \Magento\Review\Model\ReviewFactory
41+
* @var ReviewFactory
3642
*/
3743
protected $_reviewFactory;
3844

@@ -42,20 +48,29 @@ class ReviewRenderer extends \Magento\Framework\View\Element\Template implements
4248
private $reviewSummaryFactory;
4349

4450
/**
45-
* @param \Magento\Framework\View\Element\Template\Context $context
46-
* @param \Magento\Review\Model\ReviewFactory $reviewFactory
51+
* @var AppendSummaryDataFactory
52+
*/
53+
private $appendSummaryDataFactory;
54+
55+
/**
56+
* @param Context $context
57+
* @param ReviewFactory $reviewFactory
4758
* @param array $data
48-
* @param ReviewSummaryFactory $reviewSummaryFactory
59+
* @param ReviewSummaryFactory|null $reviewSummaryFactory
60+
* @param AppendSummaryDataFactory|null $appendSummaryDataFactory
4961
*/
5062
public function __construct(
51-
\Magento\Framework\View\Element\Template\Context $context,
52-
\Magento\Review\Model\ReviewFactory $reviewFactory,
63+
Context $context,
64+
ReviewFactory $reviewFactory,
5365
array $data = [],
54-
ReviewSummaryFactory $reviewSummaryFactory = null
66+
ReviewSummaryFactory $reviewSummaryFactory = null,
67+
AppendSummaryDataFactory $appendSummaryDataFactory = null
5568
) {
5669
$this->_reviewFactory = $reviewFactory;
5770
$this->reviewSummaryFactory = $reviewSummaryFactory ??
5871
ObjectManager::getInstance()->get(ReviewSummaryFactory::class);
72+
$this->appendSummaryDataFactory = $appendSummaryDataFactory ??
73+
ObjectManager::getInstance()->get(AppendSummaryDataFactory::class);
5974
parent::__construct($context, $data);
6075
}
6176

@@ -68,7 +83,7 @@ public function isReviewEnabled(): string
6883
{
6984
return $this->_scopeConfig->getValue(
7085
PredispatchReviewObserver::XML_PATH_REVIEW_ACTIVE,
71-
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
86+
ScopeInterface::SCOPE_STORE
7287
);
7388
}
7489

@@ -80,19 +95,21 @@ public function isReviewEnabled(): string
8095
* @param bool $displayIfNoReviews
8196
*
8297
* @return string
83-
* @throws \Magento\Framework\Exception\LocalizedException
84-
* @throws \Magento\Framework\Exception\NoSuchEntityException
98+
* @throws LocalizedException
99+
* @throws NoSuchEntityException
85100
*/
86101
public function getReviewsSummaryHtml(
87-
\Magento\Catalog\Model\Product $product,
102+
Product $product,
88103
$templateType = self::DEFAULT_VIEW,
89104
$displayIfNoReviews = false
90105
) {
91106
if ($product->getRatingSummary() === null) {
92-
$this->reviewSummaryFactory->create()->appendSummaryDataToObject(
93-
$product,
94-
$this->_storeManager->getStore()->getId()
95-
);
107+
$this->appendSummaryDataFactory->create()
108+
->execute(
109+
$product,
110+
$this->_storeManager->getStore()->getId(),
111+
Review::ENTITY_PRODUCT_CODE
112+
);
96113
}
97114

98115
if (null === $product->getRatingSummary() && !$displayIfNoReviews) {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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;
9+
10+
use Magento\Framework\Model\AbstractModel;
11+
use Magento\Review\Model\ResourceModel\Review\Summary\CollectionFactory as SummaryCollectionFactory;
12+
13+
/**
14+
* Add review summary data to object by its entity code
15+
*/
16+
class AppendSummaryData
17+
{
18+
/**
19+
* @var SummaryCollectionFactory
20+
*/
21+
private $summaryCollectionFactory;
22+
23+
/**
24+
* @param SummaryCollectionFactory $summaryCollectionFactory
25+
*/
26+
public function __construct(
27+
SummaryCollectionFactory $summaryCollectionFactory
28+
) {
29+
$this->summaryCollectionFactory = $summaryCollectionFactory;
30+
}
31+
32+
/**
33+
* Append summary data to object filtered by its entity code
34+
*
35+
* @param AbstractModel $object
36+
* @param int $storeId
37+
* @param string $entityCode
38+
* @retrun void
39+
*/
40+
public function execute(AbstractModel $object, int $storeId, string $entityCode): void
41+
{
42+
$summaryCollection = $this->summaryCollectionFactory->create();
43+
$summaryCollection->addStoreFilter($storeId);
44+
$summaryCollection->getSelect()
45+
->joinLeft(
46+
['review_entity' => $summaryCollection->getResource()->getTable('review_entity')],
47+
'main_table.entity_type = review_entity.entity_id',
48+
'entity_code'
49+
)
50+
->where('entity_pk_value = ?', $object->getId())
51+
->where('entity_code = ?', $entityCode);
52+
$summaryItem = $summaryCollection->getFirstItem();
53+
54+
$object->addData(
55+
[
56+
'reviews_count' => $summaryItem->getData('reviews_count'),
57+
'rating_summary' => $summaryItem->getData('rating_summary'),
58+
]
59+
);
60+
}
61+
}

app/code/Magento/Review/Model/ReviewSummary.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
/**
1414
* ReviewSummary model.
15+
*
16+
* @deprecated Filtering collection by entity_type ID leads to wrong result if AUTO_INCREMENT begins not form 1.
17+
* @see \Magento\Review\Model\AppendSummaryData
1518
*/
1619
class ReviewSummary
1720
{
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
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\Test\Unit\Model;
9+
10+
use Magento\Catalog\Model\Product;
11+
use Magento\Framework\DB\Select;
12+
use Magento\Review\Model\AppendSummaryData;
13+
use Magento\Review\Model\ResourceModel\Review\Summary as ResourceSummary;
14+
use Magento\Review\Model\ResourceModel\Review\Summary\Collection as SummaryCollection;
15+
use Magento\Review\Model\ResourceModel\Review\Summary\CollectionFactory as SummaryCollectionFactory;
16+
use Magento\Review\Model\Review\Summary;
17+
use PHPUnit\Framework\MockObject\MockObject;
18+
use PHPUnit\Framework\TestCase;
19+
20+
/**
21+
* Unit tests for \Magento\Review\Model\AppendSummaryData class
22+
*/
23+
class AppendSummaryDataTest extends TestCase
24+
{
25+
/**
26+
* @var SummaryCollectionFactory|MockObject
27+
*/
28+
private $summaryCollectionFactoryMock;
29+
30+
/**
31+
* @var Product|MockObject
32+
*/
33+
private $productMock;
34+
35+
/**
36+
* @var Summary|MockObject
37+
*/
38+
private $summaryMock;
39+
40+
/**
41+
* @var SummaryCollection|MockObject
42+
*/
43+
private $summaryCollectionMock;
44+
45+
/**
46+
* @var Select|MockObject
47+
*/
48+
private $selectMock;
49+
50+
/**
51+
* @var ResourceSummary|MockObject
52+
*/
53+
private $resourceSummaryMock;
54+
55+
/**
56+
* @var AppendSummaryData
57+
*/
58+
private $model;
59+
60+
/**
61+
* @inheriDoc
62+
*/
63+
protected function setUp(): void
64+
{
65+
$this->summaryCollectionFactoryMock = $this->getMockBuilder(SummaryCollectionFactory::class)
66+
->disableOriginalConstructor()
67+
->onlyMethods(['create'])
68+
->getMock();
69+
70+
$this->productMock = $this->getMockBuilder(Product::class)
71+
->disableOriginalConstructor()
72+
->onlyMethods(['getId', 'addData'])
73+
->getMock();
74+
75+
$this->summaryMock = $this->getMockBuilder(Summary::class)
76+
->disableOriginalConstructor()
77+
->onlyMethods(['getData'])
78+
->getMock();
79+
80+
$this->summaryCollectionMock = $this->getMockBuilder(SummaryCollection::class)
81+
->disableOriginalConstructor()
82+
->onlyMethods(
83+
[
84+
'addStoreFilter',
85+
'getSelect',
86+
'getResource',
87+
'getFirstItem',
88+
]
89+
)
90+
->getMock();
91+
92+
$this->selectMock = $this->getMockBuilder(Select::class)
93+
->disableOriginalConstructor()
94+
->onlyMethods(['joinLeft', 'where'])
95+
->getMock();
96+
97+
$this->resourceSummaryMock = $this->getMockBuilder(ResourceSummary::class)
98+
->disableOriginalConstructor()
99+
->onlyMethods(['getTable'])
100+
->getMock();
101+
102+
$this->model = new AppendSummaryData(
103+
$this->summaryCollectionFactoryMock
104+
);
105+
}
106+
107+
/**
108+
* @return void
109+
*/
110+
public function testExecute(): void
111+
{
112+
$productId = 6;
113+
$storeId = 4;
114+
$entityCode = 'product';
115+
$summaryData = [
116+
'reviews_count' => 2,
117+
'rating_summary' => 80,
118+
];
119+
120+
$this->productMock->expects($this->once())
121+
->method('getId')
122+
->willReturn($productId);
123+
124+
$this->productMock->expects($this->once())
125+
->method('addData')
126+
->with($summaryData)
127+
->willReturnSelf();
128+
129+
$this->summaryMock->expects($this->exactly(2))
130+
->method('getData')
131+
->willReturnMap(
132+
[
133+
['reviews_count', null, $summaryData['reviews_count']],
134+
['rating_summary', null, $summaryData['rating_summary']],
135+
]
136+
);
137+
138+
$this->summaryCollectionMock->expects($this->once())
139+
->method('addStoreFilter')
140+
->with($storeId)
141+
->willReturnSelf();
142+
$this->summaryCollectionMock->expects($this->once())
143+
->method('getSelect')
144+
->willReturn($this->selectMock);
145+
$this->summaryCollectionMock->expects($this->once())
146+
->method('getResource')
147+
->willReturn($this->resourceSummaryMock);
148+
149+
$this->resourceSummaryMock->expects($this->once())
150+
->method('getTable')
151+
->willReturn('table_name');
152+
153+
$this->summaryCollectionMock->expects($this->once())
154+
->method('getFirstItem')
155+
->willReturn($this->summaryMock);
156+
157+
$this->selectMock->expects($this->once())
158+
->method('joinLeft')
159+
->willReturnSelf();
160+
$this->selectMock->expects($this->exactly(2))
161+
->method('where')
162+
->willReturnSelf();
163+
164+
$this->summaryCollectionFactoryMock->expects($this->once())
165+
->method('create')
166+
->willReturn($this->summaryCollectionMock);
167+
168+
$this->model->execute($this->productMock, $storeId, $entityCode);
169+
}
170+
}

0 commit comments

Comments
 (0)