diff --git a/app/code/Magento/Downloadable/Controller/Download/Sample.php b/app/code/Magento/Downloadable/Controller/Download/Sample.php
index e2561092a7592..839083b320878 100644
--- a/app/code/Magento/Downloadable/Controller/Download/Sample.php
+++ b/app/code/Magento/Downloadable/Controller/Download/Sample.php
@@ -3,14 +3,21 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
declare(strict_types=1);
namespace Magento\Downloadable\Controller\Download;
+use Magento\Downloadable\Controller\Download;
use Magento\Downloadable\Helper\Download as DownloadHelper;
+use Magento\Downloadable\Helper\File;
use Magento\Downloadable\Model\RelatedProductRetriever;
use Magento\Downloadable\Model\Sample as SampleModel;
+use Magento\Downloadable\Model\SampleFactory;
use Magento\Framework\App\Action\Context;
+use Magento\Catalog\Model\Product\Attribute\Source\Status;
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResponseInterface;
/**
@@ -18,24 +25,49 @@
*
* @SuppressWarnings(PHPMD.AllPurposeAction)
*/
-class Sample extends \Magento\Downloadable\Controller\Download
+class Sample extends Download
{
/**
* @var RelatedProductRetriever
*/
private $relatedProductRetriever;
+ /**
+ * @var File
+ */
+ private $file;
+
+ /**
+ * @var SampleFactory
+ */
+ private $sampleFactory;
+
+ /**
+ * @var StockConfigurationInterface
+ */
+ private $stockConfiguration;
+
/**
* @param Context $context
* @param RelatedProductRetriever $relatedProductRetriever
+ * @param File|null $file
+ * @param SampleFactory|null $sampleFactory
+ * @param StockConfigurationInterface|null $stockConfiguration
*/
public function __construct(
Context $context,
- RelatedProductRetriever $relatedProductRetriever
+ RelatedProductRetriever $relatedProductRetriever,
+ ?File $file = null,
+ ?SampleFactory $sampleFactory = null,
+ ?StockConfigurationInterface $stockConfiguration = null
) {
parent::__construct($context);
$this->relatedProductRetriever = $relatedProductRetriever;
+ $this->file = $file ?: ObjectManager::getInstance()->get(File::class);
+ $this->sampleFactory = $sampleFactory ?: ObjectManager::getInstance()->get(SampleFactory::class);
+ $this->stockConfiguration = $stockConfiguration
+ ?: ObjectManager::getInstance()->get(StockConfigurationInterface::class);
}
/**
@@ -47,43 +79,60 @@ public function execute()
{
$sampleId = $this->getRequest()->getParam('sample_id', 0);
/** @var SampleModel $sample */
- $sample = $this->_objectManager->create(SampleModel::class);
+ $sample = $this->sampleFactory->create();
$sample->load($sampleId);
- if ($sample->getId() && $this->isProductSalable($sample)) {
- $resource = '';
- $resourceType = '';
- if ($sample->getSampleType() == DownloadHelper::LINK_TYPE_URL) {
- $resource = $sample->getSampleUrl();
- $resourceType = DownloadHelper::LINK_TYPE_URL;
- } elseif ($sample->getSampleType() == DownloadHelper::LINK_TYPE_FILE) {
- /** @var \Magento\Downloadable\Helper\File $helper */
- $helper = $this->_objectManager->get(\Magento\Downloadable\Helper\File::class);
- $resource = $helper->getFilePath($sample->getBasePath(), $sample->getSampleFile());
- $resourceType = DownloadHelper::LINK_TYPE_FILE;
- }
- try {
- $this->_processDownload($resource, $resourceType);
- // phpcs:ignore Magento2.Security.LanguageConstruct.ExitUsage
- exit(0);
- } catch (\Exception $e) {
- $this->messageManager->addError(
- __('Sorry, there was an error getting requested content. Please contact the store owner.')
- );
- }
+ if ($this->isCanDownload($sample)) {
+ $this->download($sample);
}
return $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
}
/**
- * Check is related product salable.
+ * Is sample can be downloaded
*
* @param SampleModel $sample
* @return bool
*/
- private function isProductSalable(SampleModel $sample): bool
+ private function isCanDownload(SampleModel $sample): bool
{
$product = $this->relatedProductRetriever->getProduct((int) $sample->getProductId());
- return $product ? $product->isSalable() : false;
+ if ($product && $sample->getId()) {
+ $isProductEnabled = (int) $product->getStatus() === Status::STATUS_ENABLED;
+
+ return $product->isSalable() || $this->stockConfiguration->isShowOutOfStock() && $isProductEnabled;
+ }
+
+ return false;
+ }
+
+ /**
+ * Download process
+ *
+ * @param SampleModel $sample
+ * @return void
+ */
+ private function download(SampleModel $sample): void
+ {
+ $resource = '';
+ $resourceType = '';
+
+ if ($sample->getSampleType() === DownloadHelper::LINK_TYPE_URL) {
+ $resource = $sample->getSampleUrl();
+ $resourceType = DownloadHelper::LINK_TYPE_URL;
+ } elseif ($sample->getSampleType() === DownloadHelper::LINK_TYPE_FILE) {
+ $resource = $this->file->getFilePath($sample->getBasePath(), $sample->getSampleFile());
+ $resourceType = DownloadHelper::LINK_TYPE_FILE;
+ }
+
+ try {
+ $this->_processDownload($resource, $resourceType);
+ // phpcs:ignore Magento2.Security.LanguageConstruct.ExitUsage
+ exit(0);
+ } catch (\Exception $e) {
+ $this->messageManager->addErrorMessage(
+ __('Sorry, there was an error getting requested content. Please contact the store owner.')
+ );
+ }
}
}
diff --git a/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml
index 2986532ef1138..9dca730dfd5c5 100644
--- a/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml
+++ b/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml
@@ -105,4 +105,15 @@
downloadableLink1
downloadableLink2
+
+ downloadableproduct
+ downloadable
+ 4
+ DownloadableProduct
+ 99.99
+ 50
+ 1
+ 0
+ downloadableproduct
+
diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/VerifyOutOfStockDownloadableProductSamplesAreAccessibleTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/VerifyOutOfStockDownloadableProductSamplesAreAccessibleTest.xml
new file mode 100644
index 0000000000000..337d4c7dd38b5
--- /dev/null
+++ b/app/code/Magento/Downloadable/Test/Mftf/Test/VerifyOutOfStockDownloadableProductSamplesAreAccessibleTest.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+