Skip to content

Commit f9d4e0a

Browse files
fix samples accessible when product is out of stock
1 parent def5104 commit f9d4e0a

File tree

3 files changed

+165
-27
lines changed

3 files changed

+165
-27
lines changed

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

Lines changed: 76 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,71 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
declare(strict_types=1);
78

89
namespace Magento\Downloadable\Controller\Download;
910

11+
use Magento\Downloadable\Controller\Download;
1012
use Magento\Downloadable\Helper\Download as DownloadHelper;
13+
use Magento\Downloadable\Helper\File;
1114
use Magento\Downloadable\Model\RelatedProductRetriever;
1215
use Magento\Downloadable\Model\Sample as SampleModel;
16+
use Magento\Downloadable\Model\SampleFactory;
1317
use Magento\Framework\App\Action\Context;
18+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
19+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
20+
use Magento\Framework\App\ObjectManager;
1421
use Magento\Framework\App\ResponseInterface;
1522

1623
/**
1724
* Class Sample executes download sample action.
1825
*
1926
* @SuppressWarnings(PHPMD.AllPurposeAction)
2027
*/
21-
class Sample extends \Magento\Downloadable\Controller\Download
28+
class Sample extends Download
2229
{
2330
/**
2431
* @var RelatedProductRetriever
2532
*/
2633
private $relatedProductRetriever;
2734

35+
/**
36+
* @var File
37+
*/
38+
private $file;
39+
40+
/**
41+
* @var SampleFactory
42+
*/
43+
private $sampleFactory;
44+
45+
/**
46+
* @var StockConfigurationInterface
47+
*/
48+
private $stockConfiguration;
49+
2850
/**
2951
* @param Context $context
3052
* @param RelatedProductRetriever $relatedProductRetriever
53+
* @param File|null $file
54+
* @param SampleFactory|null $sampleFactory
55+
* @param StockConfigurationInterface|null $stockConfiguration
3156
*/
3257
public function __construct(
3358
Context $context,
34-
RelatedProductRetriever $relatedProductRetriever
59+
RelatedProductRetriever $relatedProductRetriever,
60+
?File $file = null,
61+
?SampleFactory $sampleFactory = null,
62+
?StockConfigurationInterface $stockConfiguration = null
3563
) {
3664
parent::__construct($context);
3765

3866
$this->relatedProductRetriever = $relatedProductRetriever;
67+
$this->file = $file ?: ObjectManager::getInstance()->get(File::class);
68+
$this->sampleFactory = $sampleFactory ?: ObjectManager::getInstance()->get(SampleFactory::class);
69+
$this->stockConfiguration = $stockConfiguration
70+
?: ObjectManager::getInstance()->get(StockConfigurationInterface::class);
3971
}
4072

4173
/**
@@ -47,43 +79,60 @@ public function execute()
4779
{
4880
$sampleId = $this->getRequest()->getParam('sample_id', 0);
4981
/** @var SampleModel $sample */
50-
$sample = $this->_objectManager->create(SampleModel::class);
82+
$sample = $this->sampleFactory->create();
5183
$sample->load($sampleId);
52-
if ($sample->getId() && $this->isProductSalable($sample)) {
53-
$resource = '';
54-
$resourceType = '';
55-
if ($sample->getSampleType() == DownloadHelper::LINK_TYPE_URL) {
56-
$resource = $sample->getSampleUrl();
57-
$resourceType = DownloadHelper::LINK_TYPE_URL;
58-
} elseif ($sample->getSampleType() == DownloadHelper::LINK_TYPE_FILE) {
59-
/** @var \Magento\Downloadable\Helper\File $helper */
60-
$helper = $this->_objectManager->get(\Magento\Downloadable\Helper\File::class);
61-
$resource = $helper->getFilePath($sample->getBasePath(), $sample->getSampleFile());
62-
$resourceType = DownloadHelper::LINK_TYPE_FILE;
63-
}
64-
try {
65-
$this->_processDownload($resource, $resourceType);
66-
// phpcs:ignore Magento2.Security.LanguageConstruct.ExitUsage
67-
exit(0);
68-
} catch (\Exception $e) {
69-
$this->messageManager->addError(
70-
__('Sorry, there was an error getting requested content. Please contact the store owner.')
71-
);
72-
}
84+
if ($this->isCanDownload($sample)) {
85+
$this->download($sample);
7386
}
7487

7588
return $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
7689
}
7790

7891
/**
79-
* Check is related product salable.
92+
* Is sample can be downloaded
8093
*
8194
* @param SampleModel $sample
8295
* @return bool
8396
*/
84-
private function isProductSalable(SampleModel $sample): bool
97+
private function isCanDownload(SampleModel $sample): bool
8598
{
8699
$product = $this->relatedProductRetriever->getProduct((int) $sample->getProductId());
87-
return $product ? $product->isSalable() : false;
100+
if ($product && $sample->getId()) {
101+
$isProductEnabled = (int) $product->getStatus() === Status::STATUS_ENABLED;
102+
103+
return $product->isSalable() || $this->stockConfiguration->isShowOutOfStock() && $isProductEnabled;
104+
}
105+
106+
return false;
107+
}
108+
109+
/**
110+
* Download process
111+
*
112+
* @param SampleModel $sample
113+
* @return void
114+
*/
115+
private function download(SampleModel $sample): void
116+
{
117+
$resource = '';
118+
$resourceType = '';
119+
120+
if ($sample->getSampleType() === DownloadHelper::LINK_TYPE_URL) {
121+
$resource = $sample->getSampleUrl();
122+
$resourceType = DownloadHelper::LINK_TYPE_URL;
123+
} elseif ($sample->getSampleType() === DownloadHelper::LINK_TYPE_FILE) {
124+
$resource = $this->file->getFilePath($sample->getBasePath(), $sample->getSampleFile());
125+
$resourceType = DownloadHelper::LINK_TYPE_FILE;
126+
}
127+
128+
try {
129+
$this->_processDownload($resource, $resourceType);
130+
// phpcs:ignore Magento2.Security.LanguageConstruct.ExitUsage
131+
exit(0);
132+
} catch (\Exception $e) {
133+
$this->messageManager->addErrorMessage(
134+
__('Sorry, there was an error getting requested content. Please contact the store owner.')
135+
);
136+
}
88137
}
89138
}

app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,15 @@
105105
<requiredEntity type="downloadable_link">downloadableLink1</requiredEntity>
106106
<requiredEntity type="downloadable_link">downloadableLink2</requiredEntity>
107107
</entity>
108+
<entity name="DownloadableProductWithoutLinksOutOfStock" type="product">
109+
<data key="sku" unique="suffix">downloadableproduct</data>
110+
<data key="type_id">downloadable</data>
111+
<data key="attribute_set_id">4</data>
112+
<data key="name" unique="suffix">DownloadableProduct</data>
113+
<data key="price">99.99</data>
114+
<data key="quantity">50</data>
115+
<data key="status">1</data>
116+
<data key="is_in_stock">0</data>
117+
<data key="urlKey" unique="suffix">downloadableproduct</data>
118+
</entity>
108119
</entities>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="VerifyOutOfStockDownloadableProductSamplesAreAccessibleTest">
12+
<annotations>
13+
<features value="Downloadable"/>
14+
<stories value="Downloadable product"/>
15+
<title value="Samples of Downloadable Products are accessible, if product is out of stock"/>
16+
<description value="Samples of Downloadable Products are accessible, if product is out of stock"/>
17+
<severity value="MAJOR"/>
18+
<group value="downloadable"/>
19+
<group value="catalog"/>
20+
</annotations>
21+
<before>
22+
<!-- Enable show out of stock product -->
23+
<magentoCLI stepKey="enableShowOutOfStockProduct" command="config:set cataloginventory/options/show_out_of_stock 1"/>
24+
25+
<!-- Add downloadable domains -->
26+
<magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/>
27+
28+
<!-- Create category -->
29+
<createData entity="_defaultCategory" stepKey="createCategory"/>
30+
31+
<!-- Create downloadable product -->
32+
<createData entity="DownloadableProductWithoutLinksOutOfStock" stepKey="createProduct">
33+
<requiredEntity createDataKey="createCategory"/>
34+
</createData>
35+
36+
<!-- Add downloadable link -->
37+
<createData entity="downloadableLink1" stepKey="addDownloadableLink">
38+
<requiredEntity createDataKey="createProduct"/>
39+
</createData>
40+
41+
<!-- Add downloadable sample -->
42+
<createData entity="DownloadableSample" stepKey="addDownloadableSample">
43+
<requiredEntity createDataKey="createProduct"/>
44+
</createData>
45+
</before>
46+
<after>
47+
<!-- Disable show out of stock product -->
48+
<magentoCLI stepKey="enableShowOutOfStockProduct" command="config:set cataloginventory/options/show_out_of_stock 0"/>
49+
50+
<!-- Remove downloadable domains -->
51+
<magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/>
52+
53+
<!-- Delete product -->
54+
<deleteData createDataKey="createProduct" stepKey="deleteDownloadableProduct"/>
55+
56+
<!-- Delete category -->
57+
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
58+
59+
<!-- Admin logout -->
60+
<actionGroup ref="AdminLogoutActionGroup" stepKey="adminLogout"/>
61+
</after>
62+
63+
<!-- Open Downloadable product from precondition on Storefront -->
64+
<actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="openStorefrontProductPage">
65+
<argument name="productUrl" value="$createProduct.custom_attributes[url_key]$"/>
66+
</actionGroup>
67+
68+
<!-- Sample url is accessible -->
69+
<actionGroup ref="AssertStorefrontSeeElementActionGroup" stepKey="seeDownloadableSample">
70+
<argument name="selector" value="{{StorefrontDownloadableProductSection.downloadableSampleLabel(DownloadableSample.title)}}"/>
71+
</actionGroup>
72+
<click selector="{{StorefrontDownloadableProductSection.downloadableSampleLabel(DownloadableSample.title)}}" stepKey="clickDownloadableSample"/>
73+
<switchToNextTab stepKey="switchToSampleTab"/>
74+
<wait time="2" stepKey="waitToMakeSureThereWillBeNoRedirectToHomePage"/>
75+
<seeInCurrentUrl url="downloadable/download/sample/sample_id/" stepKey="amOnSampleDownloadPage"/>
76+
<closeTab stepKey="closeSampleTab"/>
77+
</test>
78+
</tests>

0 commit comments

Comments
 (0)