Skip to content

Commit a37048b

Browse files
committed
Merge branch 'MC-31271' of https://github.com/magento-mpi/magento2ce into PR-13-02-2020
2 parents 3099a0e + 084f38c commit a37048b

File tree

4 files changed

+229
-22
lines changed

4 files changed

+229
-22
lines changed

app/code/Magento/Reports/Model/ResourceModel/Review/Customer/Collection.php

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@
1111
*/
1212
namespace Magento\Reports\Model\ResourceModel\Review\Customer;
1313

14+
use Magento\Framework\DB\Select;
15+
1416
/**
17+
* Report Customer Review collection
18+
*
1519
* @api
20+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1621
* @since 100.0.2
1722
*/
1823
class Collection extends \Magento\Review\Model\ResourceModel\Review\Collection
@@ -104,39 +109,50 @@ protected function _joinCustomers()
104109
}
105110

106111
/**
107-
* {@inheritdoc}
112+
* @inheritdoc
108113
*
109114
* Additional processing of 'customer_name' field is required, as it is a concat field, which can not be aliased.
110115
* @see _joinCustomers
111116
* @since 100.2.2
112117
*/
113118
public function addFieldToFilter($field, $condition = null)
114119
{
120+
if ($field === 'review_cnt') {
121+
$conditionSql = $this->_getConditionSql($field, $condition);
122+
$this->getSelect()->having($conditionSql, null, Select::TYPE_CONDITION);
123+
}
124+
115125
if ($field === 'customer_name') {
116126
$field = $this->getConnection()->getConcatSql(['customer.firstname', 'customer.lastname'], ' ');
117127
}
118128

119-
return parent::addFieldToFilter($field, $condition);
129+
return ($field === 'review_cnt') ? $this : parent::addFieldToFilter($field, $condition);
120130
}
121131

122132
/**
123133
* Get select count sql
124134
*
125-
* @return string
135+
* @return \Magento\Framework\DB\Select
136+
* @throws \Zend_Db_Select_Exception
126137
*/
127138
public function getSelectCountSql()
128139
{
129140
$countSelect = clone $this->getSelect();
141+
$havingClauses = $countSelect->getPart(Select::HAVING);
142+
$whereClauses = $countSelect->getPart(Select::WHERE);
130143
$countSelect->reset(\Magento\Framework\DB\Select::ORDER);
131-
$countSelect->reset(\Magento\Framework\DB\Select::GROUP);
132-
$countSelect->reset(\Magento\Framework\DB\Select::HAVING);
133144
$countSelect->reset(\Magento\Framework\DB\Select::LIMIT_COUNT);
134145
$countSelect->reset(\Magento\Framework\DB\Select::LIMIT_OFFSET);
135-
$countSelect->reset(\Magento\Framework\DB\Select::COLUMNS);
136-
$countSelect->reset(\Magento\Framework\DB\Select::WHERE);
137-
138-
$countSelect->columns(new \Zend_Db_Expr('COUNT(DISTINCT detail.customer_id)'));
139-
140-
return $countSelect;
146+
if (empty($whereClauses)) {
147+
$countSelect->reset(\Magento\Framework\DB\Select::WHERE);
148+
}
149+
if (empty($havingClauses)) {
150+
$countSelect->reset(\Magento\Framework\DB\Select::HAVING);
151+
$countSelect->columns(new \Zend_Db_Expr('COUNT(DISTINCT detail.customer_id)'));
152+
}
153+
$aggregateSelect = clone $countSelect;
154+
$aggregateSelect->reset();
155+
$aggregateSelect->from($countSelect, 'COUNT(*)');
156+
return $aggregateSelect;
141157
}
142158
}

app/code/Magento/Reports/Model/ResourceModel/Review/Product/Collection.php

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
*/
1212
namespace Magento\Reports\Model\ResourceModel\Review\Product;
1313

14+
use Magento\Framework\DB\Select;
15+
1416
/**
17+
* Review collection class
18+
*
1519
* @api
1620
* @since 100.0.2
1721
*/
@@ -51,7 +55,7 @@ protected function _joinReview()
5155
'e.entity_id = r.entity_pk_value',
5256
[
5357
'review_cnt' => new \Zend_Db_Expr(sprintf('(%s)', $subSelect)),
54-
'created_at' => 'MAX(r.created_at)'
58+
'last_review' => 'MAX(r.created_at)'
5559
]
5660
)->group(
5761
'e.entity_id'
@@ -87,33 +91,58 @@ protected function _joinReview()
8791
*/
8892
public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC)
8993
{
90-
if (in_array($attribute, ['review_cnt', 'created_at', 'avg_rating', 'avg_rating_approved'])) {
94+
if (in_array($attribute, ['review_cnt', 'last_review', 'avg_rating', 'avg_rating_approved'])) {
9195
$this->getSelect()->order($attribute . ' ' . $dir);
9296
return $this;
9397
}
9498

9599
return parent::addAttributeToSort($attribute, $dir);
96100
}
97101

102+
/**
103+
* Add attribute to filter
104+
*
105+
* @param string $attribute
106+
* @param array|null $condition
107+
* @param string $joinType
108+
* @return $this|\Magento\Catalog\Model\ResourceModel\Product\Collection
109+
*/
110+
public function addAttributeToFilter($attribute, $condition = null, $joinType = 'inner')
111+
{
112+
$aggregateFilterArray = ['review_cnt', 'last_review', 'avg_rating', 'avg_rating_approved'];
113+
if (is_string($attribute) &&
114+
in_array($attribute, $aggregateFilterArray)) {
115+
$conditionSql = $this->_getConditionSql($attribute, $condition);
116+
$this->getSelect()->having($conditionSql, null, Select::TYPE_CONDITION);
117+
}
118+
return in_array($attribute, $aggregateFilterArray) ? $this :
119+
parent::addAttributeToFilter($attribute, $condition, $joinType);
120+
}
121+
98122
/**
99123
* Get select count sql
100124
*
101125
* @return \Magento\Framework\DB\Select
126+
* @throws \Zend_Db_Select_Exception
102127
*/
103128
public function getSelectCountSql()
104129
{
105130
$this->_renderFilters();
106131

107-
/* @var \Magento\Framework\DB\Select $select */
132+
/* @var Select $select */
108133
$select = clone $this->getSelect();
109-
$select->reset(\Magento\Framework\DB\Select::ORDER);
110-
$select->reset(\Magento\Framework\DB\Select::LIMIT_COUNT);
111-
$select->reset(\Magento\Framework\DB\Select::LIMIT_OFFSET);
112-
$select->reset(\Magento\Framework\DB\Select::COLUMNS);
113-
$select->resetJoinLeft();
114-
$select->columns(new \Zend_Db_Expr('1'));
115-
116-
/* @var \Magento\Framework\DB\Select $countSelect */
134+
$havingClauses = $select->getPart(Select::HAVING);
135+
$select->reset(Select::ORDER);
136+
$select->reset(Select::LIMIT_COUNT);
137+
$select->reset(Select::LIMIT_OFFSET);
138+
139+
if (empty($havingClauses)) {
140+
$select->reset(Select::COLUMNS);
141+
$select->reset(Select::HAVING);
142+
$select->resetJoinLeft();
143+
$select->columns(new \Zend_Db_Expr('1'));
144+
}
145+
/* @var Select $countSelect */
117146
$countSelect = clone $select;
118147
$countSelect->reset();
119148
$countSelect->from($select, "COUNT(*)");
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Reports\Test\Unit\Model\ResourceModel\Review\Customer;
8+
9+
use Magento\Framework\DB\Select;
10+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
11+
use Magento\Reports\Model\ResourceModel\Review\Customer\Collection;
12+
13+
/**
14+
* Review product collection test
15+
*/
16+
class CollectionTest extends \PHPUnit\Framework\TestCase
17+
{
18+
/**
19+
* @var ObjectManager
20+
*/
21+
private $objectManager;
22+
23+
/**
24+
* @var \PHPUnit_Framework_MockObject_MockObject
25+
*/
26+
private $selectMock;
27+
28+
/**
29+
* @var \PHPUnit_Framework_MockObject_MockObject
30+
*/
31+
private $collectionMock;
32+
33+
protected function setUp()
34+
{
35+
$this->objectManager = new ObjectManager($this);
36+
$this->selectMock = $this->createMock(Select::class);
37+
$this->collectionMock = $this->getMockBuilder(Collection::class)
38+
->setMethods(['getSelect'])
39+
->disableOriginalConstructor()
40+
->getMock();
41+
$this->collectionMock->expects($this->atLeastOnce())->method('getSelect')->willReturn($this->selectMock);
42+
}
43+
44+
public function testGetSelectCountSqlWithoutHavingClauses()
45+
{
46+
$havingClauses = [];
47+
$whereClauses = [];
48+
$this->selectMock->expects($this->atLeastOnce())->method('getPart')->willReturn($havingClauses);
49+
$this->selectMock->expects($this->atLeastOnce())->method('getPart')->willReturn($whereClauses);
50+
$this->selectMock->expects($this->at(2))->method('reset')->with(Select::ORDER);
51+
$this->selectMock->expects($this->at(3))->method('reset')->with(Select::LIMIT_COUNT);
52+
$this->selectMock->expects($this->at(4))->method('reset')->with(Select::LIMIT_OFFSET);
53+
$this->selectMock->expects($this->at(5))->method('reset')->with(Select::WHERE);
54+
$this->selectMock->expects($this->at(6))->method('reset')->with(Select::HAVING);
55+
$this->selectMock->expects($this->atLeastOnce())->method('columns')
56+
->with(new \Zend_Db_Expr('COUNT(DISTINCT detail.customer_id)'))->willReturnSelf();
57+
$this->selectMock->expects($this->atLeastOnce())->method('reset')->willReturnSelf();
58+
$this->selectMock->expects($this->atLeastOnce())->method('from')->willReturnSelf();
59+
60+
$this->assertEquals($this->selectMock, $this->collectionMock->getSelectCountSql());
61+
}
62+
63+
public function testGetSelectCountSqlWithHavingClauses()
64+
{
65+
$havingClauses = [
66+
'clause-1' => '(review_cnt LIKE %4%)',
67+
'clause-2' => '(avg_rating LIKE %55.00%)'
68+
];
69+
$whereClauses = [
70+
'customer name LIKE %test%'
71+
];
72+
73+
$this->selectMock->expects($this->atLeastOnce())->method('getPart')->willReturn($havingClauses);
74+
$this->selectMock->expects($this->atLeastOnce())->method('getPart')->willReturn($whereClauses);
75+
$this->selectMock->expects($this->at(2))->method('reset')->with(Select::ORDER);
76+
$this->selectMock->expects($this->at(3))->method('reset')->with(Select::LIMIT_COUNT);
77+
$this->selectMock->expects($this->at(4))->method('reset')->with(Select::LIMIT_OFFSET);
78+
$this->selectMock->expects($this->atLeastOnce())->method('reset')->willReturnSelf();
79+
$this->selectMock->expects($this->atLeastOnce())->method('from')->willReturnSelf();
80+
81+
$this->assertEquals($this->selectMock, $this->collectionMock->getSelectCountSql());
82+
}
83+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Reports\Test\Unit\Model\ResourceModel\Review\Product;
8+
9+
use Magento\Framework\DB\Select;
10+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
11+
use Magento\Reports\Model\ResourceModel\Review\Product\Collection;
12+
13+
/**
14+
* Review product collection test
15+
*/
16+
class CollectionTest extends \PHPUnit\Framework\TestCase
17+
{
18+
/**
19+
* @var ObjectManager
20+
*/
21+
private $objectManager;
22+
23+
/**
24+
* @var \PHPUnit_Framework_MockObject_MockObject
25+
*/
26+
private $selectMock;
27+
28+
/**
29+
* @var \PHPUnit_Framework_MockObject_MockObject
30+
*/
31+
private $collectionMock;
32+
33+
protected function setUp()
34+
{
35+
$this->objectManager = new ObjectManager($this);
36+
$this->selectMock = $this->createMock(Select::class);
37+
$this->collectionMock = $this->getMockBuilder(Collection::class)
38+
->setMethods(['getSelect'])
39+
->disableOriginalConstructor()
40+
->getMock();
41+
$this->collectionMock->expects($this->atLeastOnce())->method('getSelect')->willReturn($this->selectMock);
42+
}
43+
44+
public function testGetSelectCountSqlWithoutHavingClauses()
45+
{
46+
$havingClauses = [];
47+
$this->selectMock->expects($this->atLeastOnce())->method('getPart')->willReturn($havingClauses);
48+
$this->selectMock->expects($this->at(1))->method('reset')->with(Select::ORDER);
49+
$this->selectMock->expects($this->at(2))->method('reset')->with(Select::LIMIT_COUNT);
50+
$this->selectMock->expects($this->at(3))->method('reset')->with(Select::LIMIT_OFFSET);
51+
$this->selectMock->expects($this->atLeastOnce())->method('columns')
52+
->with(new \Zend_Db_Expr('1'))->willReturnSelf();
53+
$this->selectMock->expects($this->atLeastOnce())->method('resetJoinLeft')->willReturnSelf();
54+
55+
$this->selectMock->expects($this->at(4))->method('reset')->with(Select::COLUMNS);
56+
$this->selectMock->expects($this->at(5))->method('reset')->with(Select::HAVING);
57+
$this->selectMock->expects($this->atLeastOnce())->method('reset')->willReturnSelf();
58+
$this->selectMock->expects($this->atLeastOnce())->method('from')->willReturnSelf();
59+
60+
$this->assertEquals($this->selectMock, $this->collectionMock->getSelectCountSql());
61+
}
62+
63+
public function testGetSelectCountSqlWithHavingClauses()
64+
{
65+
$havingClauses = [
66+
'clause-1' => '(review_cnt LIKE %4%)',
67+
'clause-2' => '(avg_rating LIKE %55.00%)'
68+
];
69+
70+
$this->selectMock->expects($this->atLeastOnce())->method('getPart')->willReturn($havingClauses);
71+
$this->selectMock->expects($this->at(1))->method('reset')->with(Select::ORDER);
72+
$this->selectMock->expects($this->at(2))->method('reset')->with(Select::LIMIT_COUNT);
73+
$this->selectMock->expects($this->at(3))->method('reset')->with(Select::LIMIT_OFFSET);
74+
$this->selectMock->expects($this->atLeastOnce())->method('reset')->willReturnSelf();
75+
$this->selectMock->expects($this->atLeastOnce())->method('from')->willReturnSelf();
76+
77+
$this->assertEquals($this->selectMock, $this->collectionMock->getSelectCountSql());
78+
}
79+
}

0 commit comments

Comments
 (0)