Skip to content

Commit b6ae02f

Browse files
authored
Merge pull request #4084 from magento-tsg/2.3-qwerty-pr48
[TSG] Upporting for 2.3 (pr48) (2.3-qwerty)
2 parents e705100 + 23d94b5 commit b6ae02f

File tree

16 files changed

+397
-128
lines changed

16 files changed

+397
-128
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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\Catalog\Model\Product;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Store\Model\StoreManagerInterface;
12+
13+
/**
14+
* Class to check that product is saleable.
15+
*/
16+
class SalabilityChecker
17+
{
18+
/**
19+
* @var ProductRepositoryInterface
20+
*/
21+
private $productRepository;
22+
23+
/**
24+
* @var StoreManagerInterface
25+
*/
26+
private $storeManager;
27+
28+
/**
29+
* @param ProductRepositoryInterface $productRepository
30+
* @param StoreManagerInterface $storeManager
31+
*/
32+
public function __construct(
33+
ProductRepositoryInterface $productRepository,
34+
StoreManagerInterface $storeManager
35+
) {
36+
$this->productRepository = $productRepository;
37+
$this->storeManager = $storeManager;
38+
}
39+
40+
/**
41+
* Check if product is salable.
42+
*
43+
* @param int|string $productId
44+
* @param int|null $storeId
45+
* @return bool
46+
*/
47+
public function isSalable($productId, $storeId = null): bool
48+
{
49+
if ($storeId === null) {
50+
$storeId = $this->storeManager->getStore()->getId();
51+
}
52+
/** @var \Magento\Catalog\Model\Product $product */
53+
$product = $this->productRepository->getById($productId, false, $storeId);
54+
55+
return $product->isSalable();
56+
}
57+
}

app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
<testCaseId value="MAGETWO-98644"/>
1818
<useCaseId value="MAGETWO-98522"/>
1919
<group value="Catalog"/>
20+
<skip>
21+
<issueId value="MC-15930"/>
22+
</skip>
2023
</annotations>
2124
<before>
2225
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>

app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ protected function getCategoriesTree($filter = null)
362362

363363
$categoryById[$category->getId()]['is_active'] = $category->getIsActive();
364364
$categoryById[$category->getId()]['label'] = $category->getName();
365+
$categoryById[$category->getId()]['__disableTmpl'] = true;
365366
$categoryById[$category->getParentId()]['optgroup'][] = &$categoryById[$category->getId()];
366367
}
367368

app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportBundleProductTest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
<testCaseId value="MC-14008"/>
1919
<group value="catalog_import_export"/>
2020
<group value="mtf_migrated"/>
21+
<skip>
22+
<issueId value="MC-15934"/>
23+
</skip>
2124
</annotations>
2225
<before>
2326
<!--Create bundle product with dynamic price with two simple products -->

app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleProductWithCustomAttributeTest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
<testCaseId value="MC-14007"/>
1919
<group value="catalog_import_export"/>
2020
<group value="mtf_migrated"/>
21+
<skip>
22+
<issueId value="MC-15934"/>
23+
</skip>
2124
</annotations>
2225
<before>
2326
<!-- Create simple product with custom attribute set -->

app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php

Lines changed: 75 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ public function __construct(
9898
}
9999

100100
/**
101+
* Return currency symbol.
102+
*
101103
* @return string
102104
*/
103105
public function getCurrencySymbol()
@@ -274,6 +276,8 @@ public function getImageUploadUrl()
274276
}
275277

276278
/**
279+
* Return product qty.
280+
*
277281
* @param Product $product
278282
* @return float
279283
*/
@@ -283,6 +287,8 @@ public function getProductStockQty(Product $product)
283287
}
284288

285289
/**
290+
* Return variation wizard.
291+
*
286292
* @param array $initData
287293
* @return string
288294
*/
@@ -298,6 +304,8 @@ public function getVariationWizard($initData)
298304
}
299305

300306
/**
307+
* Return product configuration matrix.
308+
*
301309
* @return array|null
302310
*/
303311
public function getProductMatrix()
@@ -309,17 +317,22 @@ public function getProductMatrix()
309317
}
310318

311319
/**
320+
* Return product attributes.
321+
*
312322
* @return array|null
313323
*/
314324
public function getProductAttributes()
315325
{
316326
if ($this->productAttributes === null) {
317327
$this->prepareVariations();
318328
}
329+
319330
return $this->productAttributes;
320331
}
321332

322333
/**
334+
* Prepare product variations.
335+
*
323336
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
324337
* @return void
325338
* TODO: move to class
@@ -344,36 +357,13 @@ protected function prepareVariations()
344357
$price = $product->getPrice();
345358
$variationOptions = [];
346359
foreach ($usedProductAttributes as $attribute) {
347-
if (!isset($attributes[$attribute->getAttributeId()])) {
348-
$attributes[$attribute->getAttributeId()] = [
349-
'code' => $attribute->getAttributeCode(),
350-
'label' => $attribute->getStoreLabel(),
351-
'id' => $attribute->getAttributeId(),
352-
'position' => $configurableAttributes[$attribute->getAttributeId()]['position'],
353-
'chosen' => [],
354-
];
355-
foreach ($attribute->getOptions() as $option) {
356-
if (!empty($option->getValue())) {
357-
$attributes[$attribute->getAttributeId()]['options'][] = [
358-
'attribute_code' => $attribute->getAttributeCode(),
359-
'attribute_label' => $attribute->getStoreLabel(0),
360-
'id' => $option->getValue(),
361-
'label' => $option->getLabel(),
362-
'value' => $option->getValue(),
363-
];
364-
}
365-
}
366-
}
367-
$optionId = $variation[$attribute->getId()]['value'];
368-
$variationOption = [
369-
'attribute_code' => $attribute->getAttributeCode(),
370-
'attribute_label' => $attribute->getStoreLabel(0),
371-
'id' => $optionId,
372-
'label' => $variation[$attribute->getId()]['label'],
373-
'value' => $optionId,
374-
];
375-
$variationOptions[] = $variationOption;
376-
$attributes[$attribute->getAttributeId()]['chosen'][] = $variationOption;
360+
list($attributes, $variationOptions) = $this->prepareAttributes(
361+
$attributes,
362+
$attribute,
363+
$configurableAttributes,
364+
$variation,
365+
$variationOptions
366+
);
377367
}
378368

379369
$productMatrix[] = [
@@ -387,12 +377,66 @@ protected function prepareVariations()
387377
'price' => $price,
388378
'options' => $variationOptions,
389379
'weight' => $product->getWeight(),
390-
'status' => $product->getStatus()
380+
'status' => $product->getStatus(),
381+
'__disableTmpl' => true,
391382
];
392383
}
393384
}
394385
}
395386
$this->productMatrix = $productMatrix;
396387
$this->productAttributes = array_values($attributes);
397388
}
389+
390+
/**
391+
* Prepare attributes.
392+
*
393+
* @param array $attributes
394+
* @param object $attribute
395+
* @param array $configurableAttributes
396+
* @param array $variation
397+
* @param array $variationOptions
398+
* @return array
399+
*/
400+
private function prepareAttributes(
401+
array $attributes,
402+
$attribute,
403+
array $configurableAttributes,
404+
array $variation,
405+
array $variationOptions
406+
): array {
407+
if (!isset($attributes[$attribute->getAttributeId()])) {
408+
$attributes[$attribute->getAttributeId()] = [
409+
'code' => $attribute->getAttributeCode(),
410+
'label' => $attribute->getStoreLabel(),
411+
'id' => $attribute->getAttributeId(),
412+
'position' => $configurableAttributes[$attribute->getAttributeId()]['position'],
413+
'chosen' => [],
414+
];
415+
foreach ($attribute->getOptions() as $option) {
416+
if (!empty($option->getValue())) {
417+
$attributes[$attribute->getAttributeId()]['options'][] = [
418+
'attribute_code' => $attribute->getAttributeCode(),
419+
'attribute_label' => $attribute->getStoreLabel(0),
420+
'id' => $option->getValue(),
421+
'label' => $option->getLabel(),
422+
'value' => $option->getValue(),
423+
'__disableTmpl' => true,
424+
];
425+
}
426+
}
427+
}
428+
$optionId = $variation[$attribute->getId()]['value'];
429+
$variationOption = [
430+
'attribute_code' => $attribute->getAttributeCode(),
431+
'attribute_label' => $attribute->getStoreLabel(0),
432+
'id' => $optionId,
433+
'label' => $variation[$attribute->getId()]['label'],
434+
'value' => $optionId,
435+
'__disableTmpl' => true,
436+
];
437+
$variationOptions[] = $variationOption;
438+
$attributes[$attribute->getAttributeId()]['chosen'][] = $variationOption;
439+
440+
return [$attributes, $variationOptions];
441+
}
398442
}

app/code/Magento/Downloadable/Controller/Download/LinkSample.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88
namespace Magento\Downloadable\Controller\Download;
99

10+
use Magento\Catalog\Model\Product\SalabilityChecker;
1011
use Magento\Downloadable\Helper\Download as DownloadHelper;
12+
use Magento\Framework\App\Action\Context;
1113
use Magento\Framework\App\ResponseInterface;
1214

1315
/**
@@ -18,7 +20,24 @@
1820
class LinkSample extends \Magento\Downloadable\Controller\Download
1921
{
2022
/**
21-
* Download link's sample action
23+
* @var SalabilityChecker
24+
*/
25+
private $salabilityChecker;
26+
27+
/**
28+
* @param Context $context
29+
* @param SalabilityChecker|null $salabilityChecker
30+
*/
31+
public function __construct(
32+
Context $context,
33+
SalabilityChecker $salabilityChecker = null
34+
) {
35+
parent::__construct($context);
36+
$this->salabilityChecker = $salabilityChecker ?: $this->_objectManager->get(SalabilityChecker::class);
37+
}
38+
39+
/**
40+
* Download link's sample action.
2241
*
2342
* @return ResponseInterface
2443
*/
@@ -27,7 +46,7 @@ public function execute()
2746
$linkId = $this->getRequest()->getParam('link_id', 0);
2847
/** @var \Magento\Downloadable\Model\Link $link */
2948
$link = $this->_objectManager->create(\Magento\Downloadable\Model\Link::class)->load($linkId);
30-
if ($link->getId()) {
49+
if ($link->getId() && $this->salabilityChecker->isSalable($link->getProductId())) {
3150
$resource = '';
3251
$resourceType = '';
3352
if ($link->getSampleType() == DownloadHelper::LINK_TYPE_URL) {
@@ -52,6 +71,7 @@ public function execute()
5271
);
5372
}
5473
}
74+
5575
return $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
5676
}
5777
}

app/code/Magento/Downloadable/Controller/Download/Sample.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88
namespace Magento\Downloadable\Controller\Download;
99

10+
use Magento\Catalog\Model\Product\SalabilityChecker;
1011
use Magento\Downloadable\Helper\Download as DownloadHelper;
12+
use Magento\Framework\App\Action\Context;
1113
use Magento\Framework\App\ResponseInterface;
1214

1315
/**
@@ -18,7 +20,24 @@
1820
class Sample extends \Magento\Downloadable\Controller\Download
1921
{
2022
/**
21-
* Download sample action
23+
* @var SalabilityChecker
24+
*/
25+
private $salabilityChecker;
26+
27+
/**
28+
* @param Context $context
29+
* @param SalabilityChecker|null $salabilityChecker
30+
*/
31+
public function __construct(
32+
Context $context,
33+
SalabilityChecker $salabilityChecker = null
34+
) {
35+
parent::__construct($context);
36+
$this->salabilityChecker = $salabilityChecker ?: $this->_objectManager->get(SalabilityChecker::class);
37+
}
38+
39+
/**
40+
* Download sample action.
2241
*
2342
* @return ResponseInterface
2443
*/
@@ -27,7 +46,7 @@ public function execute()
2746
$sampleId = $this->getRequest()->getParam('sample_id', 0);
2847
/** @var \Magento\Downloadable\Model\Sample $sample */
2948
$sample = $this->_objectManager->create(\Magento\Downloadable\Model\Sample::class)->load($sampleId);
30-
if ($sample->getId()) {
49+
if ($sample->getId() && $this->salabilityChecker->isSalable($sample->getProductId())) {
3150
$resource = '';
3251
$resourceType = '';
3352
if ($sample->getSampleType() == DownloadHelper::LINK_TYPE_URL) {
@@ -49,6 +68,7 @@ public function execute()
4968
);
5069
}
5170
}
71+
5272
return $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
5373
}
5474
}

0 commit comments

Comments
 (0)