Skip to content

Commit 8ee63a1

Browse files
authored
Merge pull request #524 from magento-tango/MAGETWO-59817
Bugs: * MAGETWO-59325: Unable to add custom attribute to product * MAGETWO-54491: Match products by rule in admin not working
2 parents ebba5f8 + 8baf594 commit 8ee63a1

File tree

5 files changed

+467
-78
lines changed

5 files changed

+467
-78
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use Magento\Eav\Api\Data\AttributeInterface;
1717
use Magento\Eav\Api\Data\AttributeSetInterface;
1818
use Magento\Framework\Api\SearchCriteriaBuilder;
19-
use Magento\Framework\Api\SortOrderBuilder;
2019
use Magento\Framework\Exception\LocalizedException;
2120
use Psr\Log\LoggerInterface;
2221
use Magento\Framework\Api\ExtensionAttributesFactory;
@@ -53,11 +52,6 @@ class AddAttributeToTemplate extends \Magento\Catalog\Controller\Adminhtml\Produ
5352
*/
5453
protected $searchCriteriaBuilder;
5554

56-
/**
57-
* @var SortOrderBuilder
58-
*/
59-
protected $sortOrderBuilder;
60-
6155
/**
6256
* @var AttributeGroupInterfaceFactory
6357
*/
@@ -115,7 +109,6 @@ public function execute()
115109
$attributeGroupSearchCriteria = $this->getSearchCriteriaBuilder()
116110
->addFilter('attribute_set_id', $attributeSet->getAttributeSetId())
117111
->addFilter('attribute_group_code', $groupCode)
118-
->addSortOrder($this->getSortOrderBuilder()->setAscendingDirection()->create())
119112
->setPageSize(1)
120113
->create();
121114

@@ -252,18 +245,6 @@ private function getSearchCriteriaBuilder()
252245
return $this->searchCriteriaBuilder;
253246
}
254247

255-
/**
256-
* @return SortOrderBuilder
257-
*/
258-
private function getSortOrderBuilder()
259-
{
260-
if (null === $this->sortOrderBuilder) {
261-
$this->sortOrderBuilder = \Magento\Framework\App\ObjectManager::getInstance()
262-
->get(\Magento\Framework\Api\SortOrderBuilder::class);
263-
}
264-
return $this->sortOrderBuilder;
265-
}
266-
267248
/**
268249
* @return AttributeManagementInterface
269250
*/
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product;
7+
8+
use Magento\Catalog\Controller\Adminhtml\Product\AddAttributeToTemplate;
9+
use Magento\Framework\Exception\LocalizedException;
10+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
11+
use Magento\Backend\App\Action\Context;
12+
use Magento\Catalog\Controller\Adminhtml\Product\Builder as ProductBuilder;
13+
use Magento\Framework\Controller\Result\JsonFactory;
14+
use Magento\Framework\App\RequestInterface;
15+
use Magento\Catalog\Api\AttributeSetRepositoryInterface;
16+
use Magento\Eav\Api\Data\AttributeSetInterface;
17+
use Magento\Framework\Api\SearchCriteriaBuilder;
18+
use Magento\Framework\Api\SearchCriteria;
19+
use Magento\Eav\Api\AttributeGroupRepositoryInterface;
20+
use Magento\Eav\Api\Data\AttributeGroupSearchResultsInterface;
21+
use Magento\Eav\Api\Data\AttributeGroupInterfaceFactory;
22+
use Magento\Eav\Api\Data\AttributeGroupInterface;
23+
use Magento\Framework\Controller\Result\Json;
24+
25+
/**
26+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
27+
*/
28+
class AddAttributeToTemplateTest extends \PHPUnit_Framework_TestCase
29+
{
30+
/**
31+
* @var ObjectManager
32+
*/
33+
private $objectManager;
34+
35+
/**
36+
* @var AddAttributeToTemplate
37+
*/
38+
private $controller;
39+
40+
/**
41+
* @var Context|\PHPUnit_Framework_MockObject_MockObject
42+
*/
43+
private $contextMock;
44+
45+
/**
46+
* @var ProductBuilder|\PHPUnit_Framework_MockObject_MockObject
47+
*/
48+
private $productBuilderMock;
49+
50+
/**
51+
* @var JsonFactory|\PHPUnit_Framework_MockObject_MockObject
52+
*/
53+
private $resultJsonFactoryMock;
54+
55+
/**
56+
* @var RequestInterface|\PHPUnit_Framework_MockObject_MockObject
57+
*/
58+
private $requestMock;
59+
60+
/**
61+
* @var AttributeSetRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
62+
*/
63+
private $attributeSetRepositoryMock;
64+
65+
/**
66+
* @var AttributeSetInterface|\PHPUnit_Framework_MockObject_MockObject
67+
*/
68+
private $attributeSetInterfaceMock;
69+
70+
/**
71+
* @var SearchCriteriaBuilder|\PHPUnit_Framework_MockObject_MockObject
72+
*/
73+
private $searchCriteriaBuilderMock;
74+
75+
/**
76+
* @var SearchCriteria|\PHPUnit_Framework_MockObject_MockObject
77+
*/
78+
private $searchCriteriaMock;
79+
80+
/**
81+
* @var AttributeGroupRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
82+
*/
83+
private $attributeGroupRepositoryMock;
84+
85+
/**
86+
* @var AttributeGroupSearchResultsInterface|\PHPUnit_Framework_MockObject_MockObject
87+
*/
88+
private $attributeGroupSearchResultsMock;
89+
90+
/**
91+
* @var AttributeGroupInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject
92+
*/
93+
private $attributeGroupInterfaceFactoryMock;
94+
95+
/**
96+
* @var AttributeGroupInterface|\PHPUnit_Framework_MockObject_MockObject
97+
*/
98+
private $attributeGroupInterfaceMock;
99+
100+
/**
101+
* @var Json|\PHPUnit_Framework_MockObject_MockObject
102+
*/
103+
private $jsonMock;
104+
105+
protected function setUp()
106+
{
107+
$this->objectManager = new ObjectManager($this);
108+
$this->contextMock = $this->getMockBuilder(Context::class)
109+
->disableOriginalConstructor()
110+
->getMock();
111+
$this->productBuilderMock = $this->getMockBuilder(ProductBuilder::class)
112+
->disableOriginalConstructor()
113+
->getMock();
114+
$this->resultJsonFactoryMock = $this->getMockBuilder(JsonFactory::class)
115+
->disableOriginalConstructor()
116+
->setMethods(['create'])
117+
->getMock();
118+
$this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)
119+
->setMethods(['getParam', 'setParam'])
120+
->getMockForAbstractClass();
121+
$this->contextMock->expects($this->once())
122+
->method('getRequest')
123+
->willReturn($this->requestMock);
124+
$this->attributeSetRepositoryMock = $this->getMockBuilder(AttributeSetRepositoryInterface::class)
125+
->setMethods(['get'])
126+
->getMockForAbstractClass();
127+
$this->attributeSetInterfaceMock = $this->getMockBuilder(AttributeSetInterface::class)
128+
->getMockForAbstractClass();
129+
$this->searchCriteriaBuilderMock = $this->getMockBuilder(SearchCriteriaBuilder::class)
130+
->disableOriginalConstructor()
131+
->setMethods(['addFilter', 'create', 'setPageSize'])
132+
->getMockForAbstractClass();
133+
$this->searchCriteriaMock = $this->getMockBuilder(SearchCriteria::class)
134+
->disableOriginalConstructor()
135+
->getMock();
136+
$this->attributeGroupRepositoryMock = $this->getMockBuilder(AttributeGroupRepositoryInterface::class)
137+
->setMethods(['getList'])
138+
->getMockForAbstractClass();
139+
$this->attributeGroupSearchResultsMock = $this->getMockBuilder(AttributeGroupSearchResultsInterface::class)
140+
->setMethods(['getItems'])
141+
->getMockForAbstractClass();
142+
$this->attributeGroupInterfaceFactoryMock = $this->getMockBuilder(AttributeGroupInterfaceFactory::class)
143+
->setMethods(['create'])
144+
->disableOriginalConstructor()
145+
->getMock();
146+
$this->attributeGroupInterfaceMock = $this->getMockBuilder(AttributeGroupInterface::class)
147+
->setMethods(['getExtensionAttributes'])
148+
->getMockForAbstractClass();
149+
$this->jsonMock = $this->getMockBuilder(Json::class)
150+
->disableOriginalConstructor()
151+
->getMock();
152+
153+
$this->controller = $this->objectManager->getObject(
154+
AddAttributeToTemplate::class,
155+
[
156+
'context' => $this->contextMock,
157+
'productBuilder' => $this->productBuilderMock,
158+
'resultJsonFactory' => $this->resultJsonFactoryMock,
159+
]
160+
);
161+
162+
$this->objectManager->setBackwardCompatibleProperty(
163+
$this->controller,
164+
'attributeSetRepository',
165+
$this->attributeSetRepositoryMock
166+
);
167+
$this->objectManager->setBackwardCompatibleProperty(
168+
$this->controller,
169+
'searchCriteriaBuilder',
170+
$this->searchCriteriaBuilderMock
171+
);
172+
$this->objectManager->setBackwardCompatibleProperty(
173+
$this->controller,
174+
'attributeGroupRepository',
175+
$this->attributeGroupRepositoryMock
176+
);
177+
$this->objectManager->setBackwardCompatibleProperty(
178+
$this->controller,
179+
'attributeGroupFactory',
180+
$this->attributeGroupInterfaceFactoryMock
181+
);
182+
}
183+
184+
public function testExecuteWithoutAttributeGroupItems()
185+
{
186+
$groupCode = 'attributes';
187+
$groupName = 'Attributes';
188+
$groupSortOrder = '15';
189+
$templateId = '4';
190+
$attributeIds = [
191+
'selected' => ["178"],
192+
'total' => '1'
193+
];
194+
195+
$this->requestMock
196+
->expects($this->any())
197+
->method('getParam')
198+
->willReturnMap(
199+
[
200+
['groupCode', null, $groupCode],
201+
['groupName', null, $groupName],
202+
['groupSortOrder', null, $groupSortOrder],
203+
['templateId', null, $templateId],
204+
['attributeIds', [], $attributeIds]
205+
]
206+
);
207+
208+
$this->attributeSetRepositoryMock->expects($this->once())
209+
->method('get')
210+
->willReturn($this->attributeSetInterfaceMock);
211+
212+
$this->searchCriteriaBuilderMock->expects($this->any())
213+
->method('addFilter')
214+
->willReturnSelf();
215+
$this->searchCriteriaBuilderMock->expects($this->any())
216+
->method('create')
217+
->willReturn($this->searchCriteriaMock);
218+
$this->searchCriteriaBuilderMock->expects($this->once())
219+
->method('setPageSize')
220+
->willReturnSelf();
221+
$this->searchCriteriaBuilderMock->expects($this->never())
222+
->method('addSortOrder')
223+
->willReturnSelf();
224+
225+
$this->attributeGroupRepositoryMock->expects($this->once())
226+
->method('getList')
227+
->willReturn($this->attributeGroupSearchResultsMock);
228+
$this->attributeGroupSearchResultsMock->expects($this->once())
229+
->method('getItems')
230+
->willReturn(null);
231+
232+
$this->attributeGroupInterfaceFactoryMock->expects($this->once())
233+
->method('create')
234+
->willReturn($this->attributeGroupInterfaceMock);
235+
$this->attributeGroupInterfaceMock->expects($this->once())
236+
->method('getExtensionAttributes')
237+
->willThrowException(new LocalizedException(__('Could not get extension attributes')));
238+
239+
$this->resultJsonFactoryMock->expects($this->once())
240+
->method('create')
241+
->willReturn($this->jsonMock);
242+
$this->jsonMock->expects($this->once())->method('setJsonData')
243+
->willReturnSelf();
244+
245+
$this->controller->execute();
246+
}
247+
}

app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
namespace Magento\Eav\Model\Entity\Attribute\Source;
77

8+
use Magento\Framework\App\ObjectManager;
9+
use Magento\Store\Model\StoreManagerInterface;
10+
811
class Table extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
912
{
1013
/**
@@ -24,6 +27,11 @@ class Table extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
2427
*/
2528
protected $_attrOptionFactory;
2629

30+
/**
31+
* @var StoreManagerInterface
32+
*/
33+
private $storeManager;
34+
2735
/**
2836
* @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\CollectionFactory $attrOptionCollectionFactory
2937
* @param \Magento\Eav\Model\ResourceModel\Entity\Attribute\OptionFactory $attrOptionFactory
@@ -47,31 +55,51 @@ public function __construct(
4755
public function getAllOptions($withEmpty = true, $defaultValues = false)
4856
{
4957
$storeId = $this->getAttribute()->getStoreId();
58+
if ($storeId === null) {
59+
$storeId = $this->getStoreManager()->getStore()->getId();
60+
}
5061
if (!is_array($this->_options)) {
5162
$this->_options = [];
5263
}
5364
if (!is_array($this->_optionsDefault)) {
5465
$this->_optionsDefault = [];
5566
}
56-
if (!isset($this->_options[$storeId])) {
67+
$attributeId = $this->getAttribute()->getId();
68+
if (!isset($this->_options[$storeId][$attributeId])) {
5769
$collection = $this->_attrOptionCollectionFactory->create()->setPositionOrder(
5870
'asc'
5971
)->setAttributeFilter(
60-
$this->getAttribute()->getId()
72+
$attributeId
6173
)->setStoreFilter(
62-
$this->getAttribute()->getStoreId()
74+
$storeId
6375
)->load();
64-
$this->_options[$storeId] = $collection->toOptionArray();
65-
$this->_optionsDefault[$storeId] = $collection->toOptionArray('default_value');
76+
$this->_options[$storeId][$attributeId] = $collection->toOptionArray();
77+
$this->_optionsDefault[$storeId][$attributeId] = $collection->toOptionArray('default_value');
6678
}
67-
$options = $defaultValues ? $this->_optionsDefault[$storeId] : $this->_options[$storeId];
79+
$options = $defaultValues
80+
? $this->_optionsDefault[$storeId][$attributeId]
81+
: $this->_options[$storeId][$attributeId];
6882
if ($withEmpty) {
6983
$options = $this->addEmptyOption($options);
7084
}
7185

7286
return $options;
7387
}
7488

89+
/**
90+
* Get StoreManager dependency
91+
*
92+
* @return StoreManagerInterface
93+
* @deprecated
94+
*/
95+
private function getStoreManager()
96+
{
97+
if ($this->storeManager === null) {
98+
$this->storeManager = ObjectManager::getInstance()->get(StoreManagerInterface::class);
99+
}
100+
return $this->storeManager;
101+
}
102+
75103
/**
76104
* Retrieve Option values array by ids
77105
*

0 commit comments

Comments
 (0)