Skip to content

Commit 900634a

Browse files
committed
Merge branch 'develop' of github.corp.magento.com:magento2/magento2ce into MAGETWO-49154-updated
2 parents baa601f + b3a13b8 commit 900634a

File tree

16 files changed

+384
-69
lines changed

16 files changed

+384
-69
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory as ProductLinkFactory;
1010
use Magento\Catalog\Api\ProductRepositoryInterface\Proxy as ProductRepository;
1111
use Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks;
12+
use Magento\Catalog\Model\Product\Link\Resolver as LinkResolver;
13+
use Magento\Framework\App\ObjectManager;
1214

1315
/**
1416
* Class Helper
@@ -56,6 +58,11 @@ class Helper
5658
*/
5759
protected $productLinks;
5860

61+
/**
62+
* @var LinkResolver
63+
*/
64+
private $linkResolver;
65+
5966
/**
6067
* @param \Magento\Framework\App\RequestInterface $request
6168
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -194,6 +201,18 @@ public function initialize(\Magento\Catalog\Model\Product $product)
194201
return $product;
195202
}
196203

204+
/**
205+
* @deprecated
206+
* @return LinkResolver
207+
*/
208+
private function getLinkResolver()
209+
{
210+
if (!is_object($this->linkResolver)) {
211+
$this->linkResolver = ObjectManager::getInstance()->get(LinkResolver::class);
212+
}
213+
return $this->linkResolver;
214+
}
215+
197216
/**
198217
* Setting product links
199218
*
@@ -203,7 +222,7 @@ public function initialize(\Magento\Catalog\Model\Product $product)
203222
*/
204223
protected function setProductLinks(\Magento\Catalog\Model\Product $product)
205224
{
206-
$links = (array)$this->request->getParam('links', []);
225+
$links = $this->getLinkResolver()->getLinks();
207226

208227
$product->setProductLinks([]);
209228

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Model\Product\Link;
7+
8+
/**
9+
* Class Converter
10+
*/
11+
class Converter
12+
{
13+
/**
14+
* Convert product links info to array indexed by sku
15+
*
16+
* @param \Magento\Catalog\Model\Product[] $products
17+
* @return array
18+
*/
19+
protected function indexBySku(array $products)
20+
{
21+
$converted = [];
22+
foreach($products as $product) {
23+
$converted[$product->getSku()] = $product;
24+
}
25+
return $converted;
26+
}
27+
28+
/**
29+
* @param \Magento\Catalog\Model\Product $entity
30+
* @return array
31+
*/
32+
public function convertLinksToGroupedArray($entity)
33+
{
34+
$basicData = $entity->getProductLinks();
35+
$associatedProducts = $entity->getTypeInstance()->getAssociatedProducts($entity);
36+
$associatedProducts = $this->indexBySku($associatedProducts);
37+
38+
/** @var \Magento\Catalog\Api\Data\ProductLinkInterface $link */
39+
foreach ($basicData as $link) {
40+
$info = $link->getData();
41+
if ($link->getLinkType() == 'associated') {
42+
$info['id'] = $associatedProducts[$link->getLinkedProductSku()]->getId();
43+
}
44+
$info = array_merge($info, $link->getExtensionAttributes()->__toArray());
45+
$linksAsArray[$link->getLinkType()][] = $info;
46+
}
47+
return $linksAsArray;
48+
}
49+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Catalog\Model\Product\Link;
7+
8+
class Resolver
9+
{
10+
/**
11+
* @var \Magento\Framework\App\RequestInterface
12+
*/
13+
protected $request;
14+
15+
/**
16+
* @var null|array
17+
*/
18+
protected $links = null;
19+
20+
public function __construct(
21+
\Magento\Framework\App\RequestInterface $request
22+
) {
23+
$this->request = $request;
24+
}
25+
26+
27+
/**
28+
* Get stored value.
29+
* Fallback to request if none.
30+
*
31+
* @return array|null
32+
*/
33+
public function getLinks()
34+
{
35+
if (null === $this->links) {
36+
$this->links = (array)$this->request->getParam('links', []);
37+
}
38+
return $this->links;
39+
}
40+
41+
/**
42+
* Override link data from request
43+
*
44+
* @param array|null $links
45+
*/
46+
public function override($links)
47+
{
48+
$this->links = $links;
49+
}
50+
}

app/code/Magento/Catalog/Model/ProductLink/Repository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ public function delete(\Magento\Catalog\Api\Data\ProductLinkInterface $entity)
214214
if (!$linkId) {
215215
throw new NoSuchEntityException(
216216
__(
217-
'Product with SKU %1 is not linked to product with SKU %2',
217+
'Product with SKU \'%1\' is not linked to product with SKU \'%2\'',
218218
$entity->getLinkedProductSku(),
219219
$entity->getSku()
220220
)

app/code/Magento/Catalog/Model/ProductRepository.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,8 @@ public function delete(\Magento\Catalog\Api\Data\ProductInterface $product)
544544
unset($this->instances[$product->getSku()]);
545545
unset($this->instancesById[$product->getId()]);
546546
$this->resourceModel->delete($product);
547+
} catch (ValidatorException $e) {
548+
throw new CouldNotSaveException(__($e->getMessage()));
547549
} catch (\Exception $e) {
548550
throw new \Magento\Framework\Exception\StateException(
549551
__('Unable to remove product %1', $sku)

app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ class HelperTest extends \PHPUnit_Framework_TestCase
9696
*/
9797
protected $customOptionMock;
9898

99+
/**
100+
* @var \PHPUnit_Framework_MockObject_MockObject
101+
*/
102+
protected $linkResolverMock;
103+
99104
/**
100105
* @var ProductLinks
101106
*/
@@ -176,6 +181,14 @@ protected function setUp()
176181
'productLinkFactory' => $this->productLinkFactoryMock,
177182
'productRepository' => $this->productRepositoryMock,
178183
]);
184+
185+
$this->linkResolverMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Link\Resolver::class)
186+
->disableOriginalConstructor()
187+
->getMock();
188+
$helperReflection = new \ReflectionClass(get_class($this->helper));
189+
$resolverProperty = $helperReflection->getProperty('linkResolver');
190+
$resolverProperty->setAccessible(true);
191+
$resolverProperty->setValue($this->helper, $this->linkResolverMock);
179192
}
180193

181194
/**
@@ -249,10 +262,7 @@ public function testInitialize()
249262
->method('getPost')
250263
->with('use_default')
251264
->willReturn($useDefaults);
252-
$this->requestMock->expects($this->at(3))
253-
->method('getPost')
254-
->with('options_use_default')
255-
->willReturn(true);
265+
$this->linkResolverMock->expects($this->once())->method('getLinks')->willReturn([]);
256266
$this->stockFilterMock->expects($this->once())
257267
->method('filter')
258268
->with(['stock_data'])

app/code/Magento/Catalog/Test/Unit/Model/ProductLink/RepositoryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ public function testDeleteWithInvalidDataException()
272272

273273
/**
274274
* @expectedException \Magento\Framework\Exception\NoSuchEntityException
275-
* @expectedExceptionMessage Product with SKU linkedProduct is not linked to product with SKU product
275+
* @expectedExceptionMessage Product with SKU 'linkedProduct' is not linked to product with SKU 'product'
276276
*/
277277
public function testDeleteWithNoSuchEntityException()
278278
{

app/code/Magento/Checkout/CustomerData/Cart.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,15 @@ protected function getRecentItems()
150150
foreach (array_reverse($this->getAllQuoteItems()) as $item) {
151151
/* @var $item \Magento\Quote\Model\Quote\Item */
152152
if (!$item->getProduct()->isVisibleInSiteVisibility()) {
153-
$productId = $item->getProduct()->getId();
154-
$products = $this->catalogUrl->getRewriteByProductStore([$productId => $item->getStoreId()]);
155-
if (!isset($products[$productId])) {
153+
$product = $item->getOptionByCode('product_type') !== null
154+
? $item->getOptionByCode('product_type')->getProduct()
155+
: $item->getProduct();
156+
157+
$products = $this->catalogUrl->getRewriteByProductStore([$product->getId() => $item->getStoreId()]);
158+
if (!isset($products[$product->getId()])) {
156159
continue;
157160
}
158-
$urlDataObject = new \Magento\Framework\DataObject($products[$productId]);
161+
$urlDataObject = new \Magento\Framework\DataObject($products[$product->getId()]);
159162
$item->getProduct()->setUrlDataObject($urlDataObject);
160163
}
161164
$items[] = $this->itemPoolInterface->getItemData($item);

app/code/Magento/Checkout/Test/Unit/CustomerData/CartTest.php

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ public function testGetSectionData()
130130
$quoteItemMock->expects($this->once())->method('getStoreId')->willReturn($storeId);
131131

132132
$productMock->expects($this->once())->method('isVisibleInSiteVisibility')->willReturn(false);
133-
$productMock->expects($this->once())->method('getId')->willReturn($productId);
133+
$productMock->expects($this->exactly(3))->method('getId')->willReturn($productId);
134134
$productMock->expects($this->once())
135135
->method('setUrlDataObject')
136136
->with(new \Magento\Framework\DataObject($productRewrite[$productId]))
@@ -170,4 +170,109 @@ public function testGetSectionData()
170170
];
171171
$this->assertEquals($expectedResult, $this->model->getSectionData());
172172
}
173+
174+
/**
175+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
176+
*/
177+
public function testGetSectionDataWithCompositeProduct()
178+
{
179+
$summaryQty = 100;
180+
$subtotalValue = 200;
181+
$productId = 10;
182+
$storeId = 20;
183+
184+
$productRewrite = [$productId => ['rewrite' => 'product']];
185+
$itemData = ['item' => 'data'];
186+
$shortcutButtonsHtml = '<span>Buttons</span>';
187+
$subtotalMock = $this->getMock('\Magento\Framework\DataObject', ['getValue'], [], '', false);
188+
$subtotalMock->expects($this->once())->method('getValue')->willReturn($subtotalValue);
189+
$totals = ['subtotal' => $subtotalMock];
190+
191+
$quoteMock = $this->getMock(
192+
'\Magento\Quote\Model\Quote',
193+
['getTotals', 'getHasError', 'getAllVisibleItems'],
194+
[],
195+
'',
196+
false
197+
);
198+
$quoteItemMock = $this->getMock(
199+
'\Magento\Quote\Model\Quote\Item',
200+
['getProduct', 'getOptionByCode', 'getStoreId'],
201+
[],
202+
'',
203+
false
204+
);
205+
206+
$this->checkoutSessionMock->expects($this->exactly(2))->method('getQuote')->willReturn($quoteMock);
207+
$quoteMock->expects($this->once())->method('getTotals')->willReturn($totals);
208+
$quoteMock->expects($this->once())->method('getHasError')->willReturn(false);
209+
210+
$this->checkoutCartMock->expects($this->once())->method('getSummaryQty')->willReturn($summaryQty);
211+
$this->checkoutHelperMock->expects($this->once())
212+
->method('formatPrice')
213+
->with($subtotalValue)
214+
->willReturn($subtotalValue);
215+
$this->checkoutHelperMock->expects($this->once())->method('canOnepageCheckout')->willReturn(true);
216+
217+
$quoteMock->expects($this->once())->method('getAllVisibleItems')->willReturn([$quoteItemMock]);
218+
219+
$productMock = $this->getMock(
220+
'\Magento\Catalog\Model\Product',
221+
['isVisibleInSiteVisibility', 'getId', 'setUrlDataObject'],
222+
[],
223+
'',
224+
false
225+
);
226+
227+
$optionsMock = $this->getMock('\Magento\Quote\Model\Quote\Item\Option', [], [], '', false);
228+
$optionsMock->expects($this->once())->method('getProduct')->willReturn($productMock);
229+
230+
$quoteItemMock->expects($this->exactly(2))->method('getProduct')->willReturn($productMock);
231+
$quoteItemMock->expects($this->exactly(2))
232+
->method('getOptionByCode')
233+
->with('product_type')
234+
->willReturn($optionsMock);
235+
$quoteItemMock->expects($this->once())->method('getStoreId')->willReturn($storeId);
236+
237+
$productMock->expects($this->once())->method('isVisibleInSiteVisibility')->willReturn(false);
238+
$productMock->expects($this->exactly(3))->method('getId')->willReturn($productId);
239+
$productMock->expects($this->once())
240+
->method('setUrlDataObject')
241+
->with(new \Magento\Framework\DataObject($productRewrite[$productId]))
242+
->willReturnSelf();
243+
244+
$this->catalogUrlMock->expects($this->once())
245+
->method('getRewriteByProductStore')
246+
->with([$productId => $storeId])
247+
->willReturn($productRewrite);
248+
249+
$shortcutButtonsMock = $this->getMock('\Magento\Catalog\Block\ShortcutButtons', [], [], '', false);
250+
$this->layoutMock->expects($this->once())
251+
->method('createBlock')
252+
->with('Magento\Catalog\Block\ShortcutButtons')
253+
->willReturn($shortcutButtonsMock);
254+
255+
$shortcutButtonsMock->expects($this->once())->method('toHtml')->willReturn($shortcutButtonsHtml);
256+
$this->checkoutHelperMock->expects($this->once())
257+
->method('isAllowedGuestCheckout')
258+
->with($quoteMock)
259+
->willReturn(true);
260+
261+
$this->itemPoolInterfaceMock->expects($this->once())
262+
->method('getItemData')
263+
->with($quoteItemMock)
264+
->willReturn($itemData);
265+
266+
$expectedResult = [
267+
'summary_count' => 100,
268+
'subtotal' => 200,
269+
'possible_onepage_checkout' => 1,
270+
'items' => [
271+
['item' => 'data']
272+
],
273+
'extra_actions' => '<span>Buttons</span>',
274+
'isGuestCheckoutAllowed' => 1
275+
];
276+
$this->assertEquals($expectedResult, $this->model->getSectionData());
277+
}
173278
}

0 commit comments

Comments
 (0)