Skip to content

Commit 58e020c

Browse files
committed
Merge remote-tracking branch 'mpi/MPI-PR' into PRS
2 parents 44a242e + c08a89e commit 58e020c

File tree

20 files changed

+642
-264
lines changed

20 files changed

+642
-264
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Model;
7+
8+
use Magento\Catalog\Model\Indexer\Category\Product\AbstractAction;
9+
use Magento\Framework\DB\Select;
10+
use Magento\Framework\DB\Sql\UnionExpression;
11+
12+
/**
13+
* Provides info about product categories.
14+
*/
15+
class ProductCategoryList
16+
{
17+
/**
18+
* @var array
19+
*/
20+
private $categoryIdList = [];
21+
22+
/**
23+
* @var ResourceModel\Product
24+
*/
25+
private $productResource;
26+
27+
/**
28+
* @var ResourceModel\Category
29+
*/
30+
private $category;
31+
32+
/**
33+
* @param ResourceModel\Product $productResource
34+
* @param ResourceModel\Category $category
35+
*/
36+
public function __construct(
37+
ResourceModel\Product $productResource,
38+
ResourceModel\Category $category
39+
) {
40+
$this->productResource = $productResource;
41+
$this->category = $category;
42+
}
43+
44+
/**
45+
* Retrieve category id list where product is present.
46+
*
47+
* @param int $productId
48+
* @return array
49+
*/
50+
public function getCategoryIds($productId)
51+
{
52+
if (!isset($this->categoryIdList[$productId])) {
53+
$unionSelect = new UnionExpression(
54+
[
55+
$this->getCategorySelect($productId, $this->category->getCategoryProductTable()),
56+
$this->getCategorySelect(
57+
$productId,
58+
$this->productResource->getTable(AbstractAction::MAIN_INDEX_TABLE)
59+
)
60+
],
61+
Select::SQL_UNION_ALL
62+
);
63+
64+
$this->categoryIdList[$productId] = $this->productResource->getConnection()->fetchCol($unionSelect);
65+
}
66+
67+
return $this->categoryIdList[$productId];
68+
}
69+
70+
/**
71+
* Returns DB select.
72+
*
73+
* @param int $productId
74+
* @param string $tableName
75+
* @return Select
76+
*/
77+
public function getCategorySelect($productId, $tableName)
78+
{
79+
return $this->productResource->getConnection()->select()->from(
80+
$tableName,
81+
['category_id']
82+
)->where(
83+
'product_id = ?',
84+
$productId
85+
);
86+
}
87+
}

app/code/Magento/CatalogRule/Model/Rule/Condition/Product.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function validate(\Magento\Framework\Model\AbstractModel $model)
2424
{
2525
$attrCode = $this->getAttribute();
2626
if ('category_ids' == $attrCode) {
27-
return $this->validateAttribute($model->getAvailableInCategories());
27+
return parent::validate($model);
2828
}
2929

3030
$oldAttrValue = $model->getData($attrCode);

app/code/Magento/CatalogRule/Test/Unit/Model/Rule/Condition/ProductTest.php

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ class ProductTest extends \PHPUnit_Framework_TestCase
2828
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute|\PHPUnit_Framework_MockObject_MockObject */
2929
protected $eavAttributeResource;
3030

31+
/** @var \Magento\Catalog\Model\ProductCategoryList|\PHPUnit_Framework_MockObject_MockObject */
32+
private $productCategoryList;
33+
3134
protected function setUp()
3235
{
3336
$this->config = $this->getMock(\Magento\Eav\Model\Config::class, ['getAttribute'], [], '', false);
3437
$this->productModel = $this->getMock(
3538
\Magento\Catalog\Model\Product::class,
3639
[
3740
'__wakeup',
38-
'getAvailableInCategories',
3941
'hasData',
4042
'getData',
4143
'getId',
@@ -47,16 +49,16 @@ protected function setUp()
4749
'',
4850
false
4951
);
50-
$this->productResource = $this->getMock(
51-
\Magento\Catalog\Model\ResourceModel\Product::class,
52-
['loadAllAttributes',
53-
'getAttributesByCode',
54-
'getAttribute'
55-
],
56-
[],
57-
'',
58-
false
59-
);
52+
53+
$this->productCategoryList = $this->getMockBuilder(\Magento\Catalog\Model\ProductCategoryList::class)
54+
->disableOriginalConstructor()
55+
->getMock();
56+
57+
$this->productResource = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product::class)
58+
->setMethods(['loadAllAttributes', 'getAttributesByCode', 'getAttribute', 'getConnection', 'getTable'])
59+
->disableOriginalConstructor()
60+
->getMock();
61+
6062
$this->eavAttributeResource = $this->getMock(
6163
\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class,
6264
[
@@ -93,7 +95,8 @@ protected function setUp()
9395
[
9496
'config' => $this->config,
9597
'product' => $this->productModel,
96-
'productResource' => $this->productResource
98+
'productResource' => $this->productResource,
99+
'productCategoryList' => $this->productCategoryList
97100
]
98101
);
99102
}
@@ -103,12 +106,13 @@ protected function setUp()
103106
*/
104107
public function testValidateMeetsCategory()
105108
{
109+
$categoryIdList = [1, 2, 3];
110+
111+
$this->productCategoryList->method('getCategoryIds')->willReturn($categoryIdList);
106112
$this->product->setData('attribute', 'category_ids');
107113
$this->product->setData('value_parsed', '1');
108-
$this->product->setData('operator', '>=');
114+
$this->product->setData('operator', '{}');
109115

110-
$this->productModel->expects($this->once())->method('getAvailableInCategories')
111-
->will($this->returnValue('2'));
112116
$this->assertTrue($this->product->validate($this->productModel));
113117
}
114118

app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
*/
1010
namespace Magento\CatalogWidget\Model\Rule\Condition;
1111

12+
use Magento\Catalog\Model\ProductCategoryList;
13+
1214
/**
1315
* Class Product
1416
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -43,6 +45,7 @@ class Product extends \Magento\Rule\Model\Condition\Product\AbstractProduct
4345
* @param \Magento\Framework\Locale\FormatInterface $localeFormat
4446
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
4547
* @param array $data
48+
* @param ProductCategoryList $categoryList
4649
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
4750
*/
4851
public function __construct(
@@ -55,7 +58,8 @@ public function __construct(
5558
\Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection $attrSetCollection,
5659
\Magento\Framework\Locale\FormatInterface $localeFormat,
5760
\Magento\Store\Model\StoreManagerInterface $storeManager,
58-
array $data = []
61+
array $data = [],
62+
ProductCategoryList $categoryList = null
5963
) {
6064
$this->storeManager = $storeManager;
6165
parent::__construct(
@@ -67,7 +71,8 @@ public function __construct(
6771
$productResource,
6872
$attrSetCollection,
6973
$localeFormat,
70-
$data
74+
$data,
75+
$categoryList
7176
);
7277
}
7378

app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/ProductTest.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1010

11+
/**
12+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
13+
*/
1114
class ProductTest extends \PHPUnit_Framework_TestCase
1215
{
1316
/**
@@ -37,14 +40,18 @@ protected function setUp()
3740
$storeMock = $this->getMock(\Magento\Store\Api\Data\StoreInterface::class);
3841
$storeManager->expects($this->any())->method('getStore')->willReturn($storeMock);
3942
$productResource = $this->getMock(\Magento\Catalog\Model\ResourceModel\Product::class, [], [], '', false);
40-
$productResource->expects($this->any())->method('loadAllAttributes')->willReturnSelf();
41-
$productResource->expects($this->any())->method('getAttributesByCode')->willReturn([]);
43+
$productResource->expects($this->once())->method('loadAllAttributes')->willReturnSelf();
44+
$productResource->expects($this->once())->method('getAttributesByCode')->willReturn([]);
45+
$productCategoryList = $this->getMockBuilder(\Magento\Catalog\Model\ProductCategoryList::class)
46+
->disableOriginalConstructor()
47+
->getMock();
4248
$this->model = $objectManagerHelper->getObject(
4349
\Magento\CatalogWidget\Model\Rule\Condition\Product::class,
4450
[
4551
'config' => $eavConfig,
4652
'storeManager' => $storeManager,
4753
'productResource' => $productResource,
54+
'productCategoryList' => $productCategoryList,
4855
'data' => [
4956
'rule' => $ruleMock,
5057
'id' => 1

app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
namespace Magento\Rule\Model\Condition\Product;
88

9+
use Magento\Catalog\Model\ProductCategoryList;
10+
use Magento\Framework\App\ObjectManager;
11+
912
/**
1013
* Abstract Rule product condition data model
1114
*
@@ -77,6 +80,11 @@ abstract class AbstractProduct extends \Magento\Rule\Model\Condition\AbstractCon
7780
*/
7881
protected $_localeFormat;
7982

83+
/**
84+
* @var ProductCategoryList
85+
*/
86+
private $productCategoryList;
87+
8088
/**
8189
* @param \Magento\Rule\Model\Condition\Context $context
8290
* @param \Magento\Backend\Helper\Data $backendData
@@ -86,7 +94,10 @@ abstract class AbstractProduct extends \Magento\Rule\Model\Condition\AbstractCon
8694
* @param \Magento\Catalog\Model\ResourceModel\Product $productResource
8795
* @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection $attrSetCollection
8896
* @param \Magento\Framework\Locale\FormatInterface $localeFormat
97+
* @param ProductCategoryList|null $categoryList
8998
* @param array $data
99+
*
100+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
90101
*/
91102
public function __construct(
92103
\Magento\Rule\Model\Condition\Context $context,
@@ -97,7 +108,8 @@ public function __construct(
97108
\Magento\Catalog\Model\ResourceModel\Product $productResource,
98109
\Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection $attrSetCollection,
99110
\Magento\Framework\Locale\FormatInterface $localeFormat,
100-
array $data = []
111+
array $data = [],
112+
ProductCategoryList $categoryList = null
101113
) {
102114
$this->_backendData = $backendData;
103115
$this->_config = $config;
@@ -106,6 +118,7 @@ public function __construct(
106118
$this->_productResource = $productResource;
107119
$this->_attrSetCollection = $attrSetCollection;
108120
$this->_localeFormat = $localeFormat;
121+
$this->productCategoryList = $categoryList ?: ObjectManager::getInstance()->get(ProductCategoryList::class);
109122
parent::__construct($context, $data);
110123
}
111124

@@ -518,7 +531,8 @@ public function validate(\Magento\Framework\Model\AbstractModel $model)
518531
$attrCode = $this->getAttribute();
519532

520533
if ('category_ids' == $attrCode) {
521-
return $this->validateAttribute($model->getAvailableInCategories());
534+
$productId = (int)$model->getEntityId();
535+
return $this->validateAttribute($this->productCategoryList->getCategoryIds($productId));
522536
} elseif (!isset($this->_entityAttributeValues[$model->getId()])) {
523537
if (!$model->getResource()) {
524538
return false;

app/code/Magento/Rule/Test/Unit/Model/Condition/Product/AbstractProductTest.php

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ class AbstractProductTest extends \PHPUnit_Framework_TestCase
3939
*/
4040
protected $_configProperty;
4141

42+
/**
43+
* Reflection for Magento\Rule\Model\Condition\Product\AbstractProduct::$productCategoryListProperty
44+
*
45+
* @var \ReflectionProperty
46+
*/
47+
private $productCategoryListProperty;
48+
4249
protected function setUp()
4350
{
4451
$this->_condition = $this->getMockForAbstractClass(
@@ -47,6 +54,13 @@ protected function setUp()
4754
'',
4855
false
4956
);
57+
58+
$this->productCategoryListProperty = new \ReflectionProperty(
59+
\Magento\Rule\Model\Condition\Product\AbstractProduct::class,
60+
'productCategoryList'
61+
);
62+
$this->productCategoryListProperty->setAccessible(true);
63+
5064
$this->_entityAttributeValuesProperty = new \ReflectionProperty(
5165
\Magento\Rule\Model\Condition\Product\AbstractProduct::class,
5266
'_entityAttributeValues'
@@ -62,10 +76,29 @@ protected function setUp()
6276

6377
public function testValidateAttributeEqualCategoryId()
6478
{
65-
$product = $this->getMock(\Magento\Framework\Model\AbstractModel::class, ["getAttribute"], [], '', false);
79+
$product = $this->getMockBuilder(\Magento\Framework\Model\AbstractModel::class)
80+
->disableOriginalConstructor()
81+
->getMock();
6682
$this->_condition->setAttribute('category_ids');
67-
$product->setAvailableInCategories(new \Magento\Framework\DataObject());
68-
$this->assertFalse($this->_condition->validate($product));
83+
$this->_condition->setValueParsed('1');
84+
$this->_condition->setOperator('{}');
85+
86+
$productCategoryList = $this->getMockBuilder(\Magento\Catalog\Model\ProductCategoryList::class)
87+
->disableOriginalConstructor()
88+
->getMock();
89+
$productCategoryList->method('getCategoryIds')->willReturn([1, 2]);
90+
$this->productCategoryListProperty->setValue(
91+
$this->_condition,
92+
$productCategoryList
93+
);
94+
$this->_configProperty->setValue(
95+
$this->_condition,
96+
$this->getMockBuilder(\Magento\Eav\Model\Config::class)
97+
->disableOriginalConstructor()
98+
->getMock()
99+
);
100+
101+
$this->assertTrue($this->_condition->validate($product));
69102
}
70103

71104
public function testValidateEmptyEntityAttributeValues()

app/code/Magento/User/Model/Backend/Config/ObserverConfig.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ public function __construct(
3535
*/
3636
public function _isLatestPasswordExpired($latestPassword)
3737
{
38-
if (!isset($latestPassword['expires']) || $this->getAdminPasswordLifetime() == 0) {
38+
if (!isset($latestPassword['last_updated']) || $this->getAdminPasswordLifetime() == 0) {
3939
return false;
40-
} else {
41-
return (int)$latestPassword['expires'] < time();
4240
}
41+
42+
return (int)$latestPassword['last_updated'] + $this->getAdminPasswordLifetime() < time();
4343
}
4444

4545
/**

0 commit comments

Comments
 (0)