diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
index 2b809914ab71d..095ce653b5e66 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
@@ -6,13 +6,14 @@
namespace Magento\Catalog\Model\Product\Option\Type;
-use Magento\Catalog\Model\Product\Exception as ProductException;
use Magento\Catalog\Helper\Product as ProductHelper;
+use Magento\Catalog\Model\Product\Exception as ProductException;
+use Magento\Catalog\Model\Product\Type\AbstractType;
use Magento\Framework\App\Filesystem\DirectoryList;
-use Magento\Framework\Filesystem;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Filesystem;
use Magento\Framework\Serialize\Serializer\Json;
-use Magento\Framework\App\ObjectManager;
/**
* Catalog product option file type
@@ -353,10 +354,17 @@ public function getFormattedOptionValue($optionValue)
if ($value === null) {
return $optionValue;
}
+ $optionId = str_replace(
+ AbstractType::OPTION_PREFIX,
+ '',
+ (string)$this->getConfigurationItemOption()->getCode()
+ );
$customOptionUrlParams = $this->getCustomOptionUrlParams()
? $this->getCustomOptionUrlParams()
: [
'id' => $this->getConfigurationItemOption()->getId(),
+ 'item' => $this->getConfigurationItemOption()->getItemId(),
+ 'option' => $optionId,
'key' => $value['secret_key']
];
diff --git a/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php b/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php
index 14551758140b6..dd06f6e56dc7d 100644
--- a/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php
+++ b/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php
@@ -1,19 +1,25 @@
resultForwardFactory = $resultForwardFactory;
@@ -60,6 +73,9 @@ public function __construct(
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(
\Magento\Framework\Serialize\Serializer\Json::class
);
+ $this->itemCollectionFactory = $itemCollectionFactory ?: ObjectManager::getInstance()->get(
+ CollectionFactory::class
+ );
}
/**
@@ -72,6 +88,8 @@ public function __construct(
public function execute()
{
$quoteItemOptionId = $this->getRequest()->getParam('id');
+ $quoteItemId = $this->getRequest()->getParam('item');
+ $optionId = $this->getRequest()->getParam('option');
/** @var $option \Magento\Quote\Model\Quote\Item\Option */
$option = $this->_objectManager->create(
\Magento\Quote\Model\Quote\Item\Option::class
@@ -80,9 +98,35 @@ public function execute()
$resultForward = $this->resultForwardFactory->create();
if (!$option->getId()) {
+ $optionData = $this->getOptionFromSalesItem($quoteItemId, $optionId);
+ } else {
+ $optionData = $this->getOptionFromQuoteItem($option);
+ }
+
+ if ($optionData) {
+ try {
+ $info = $this->serializer->unserialize($optionData);
+ if ($this->getRequest()->getParam('key') != $info['secret_key']) {
+ return $resultForward->forward('noroute');
+ }
+ return $this->download->createResponse($info);
+ } catch (\Exception $e) {
+ return $resultForward->forward('noroute');
+ }
+ } else {
return $resultForward->forward('noroute');
}
+ $this->endExecute();
+ }
+ /**
+ * Get custom option data from quote item option
+ *
+ * @param \Magento\Quote\Model\Quote\Item\Option $option
+ * @return string|null
+ */
+ protected function getOptionFromQuoteItem($option)
+ {
$optionId = null;
if ($option->getCode() && strpos($option->getCode(), AbstractType::OPTION_PREFIX) === 0) {
$optionId = str_replace(AbstractType::OPTION_PREFIX, '', $option->getCode());
@@ -100,19 +144,37 @@ public function execute()
}
if ($productOption->getId() && $productOption->getType() != 'file') {
- return $resultForward->forward('noroute');
+ return null;
}
+ return $option->getValue();
+ }
- try {
- $info = $this->serializer->unserialize($option->getValue());
- if ($this->getRequest()->getParam('key') != $info['secret_key']) {
- return $resultForward->forward('noroute');
+ /**
+ * Get custom option data from sales item
+ *
+ * @param string|null $quoteItemId
+ * @param string|null $optionId
+ * @return string|null
+ */
+ protected function getOptionFromSalesItem($quoteItemId, $optionId)
+ {
+ if (!$quoteItemId || !$optionId) {
+ return null;
+ }
+ $collection = $this->itemCollectionFactory->create();
+ $quoteItem = $collection->addFieldToFilter(OrderItemInterface::QUOTE_ITEM_ID, $quoteItemId)->getFirstItem();
+ if ($quoteItem && $quoteItem->getId()) {
+ try {
+ $options = $quoteItem->getProductOptionByCode('options');
+ $key = array_search($optionId, array_column($options, 'option_id'));
+ if ($key !== false && $options[$key]['option_value'] && $options[$key]['option_type'] == 'file') {
+ return $options[$key]['option_value'];
+ }
+ } catch (\Exception $e) {
+ return null;
}
- return $this->download->createResponse($info);
- } catch (\Exception $e) {
- return $resultForward->forward('noroute');
}
- $this->endExecute();
+ return null;
}
/**
diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Download/DownloadCustomOptionTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Download/DownloadCustomOptionTest.php
index 4ac04cf3461e7..af68b1ae247e6 100644
--- a/app/code/Magento/Sales/Test/Unit/Controller/Download/DownloadCustomOptionTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Controller/Download/DownloadCustomOptionTest.php
@@ -1,7 +1,7 @@
onlyMethods(['serialize', 'unserialize'])
->getMock();
+ $this->itemCollectionFactoryMock = $this->getMockBuilder(CollectionFactory::class)
+ ->disableOriginalConstructor()
+ ->onlyMethods(['create'])
+ ->getMock();
+
$requestMock = $this->getMockBuilder(Http::class)
->disableOriginalConstructor()
->onlyMethods(['getParam'])
@@ -160,7 +171,8 @@ protected function setUp(): void
'resultForwardFactory' => $resultForwardFactoryMock,
'download' => $this->downloadMock,
'unserialize' => $this->createMock(Unserialize::class),
- 'serializer' => $this->serializerMock
+ 'serializer' => $this->serializerMock,
+ 'itemCollectionFactory' => $this->itemCollectionFactoryMock
]
)
->getMock();
diff --git a/app/code/Magento/Sales/etc/db_schema.xml b/app/code/Magento/Sales/etc/db_schema.xml
index 2190e78371db4..aac7e78264bbc 100644
--- a/app/code/Magento/Sales/etc/db_schema.xml
+++ b/app/code/Magento/Sales/etc/db_schema.xml
@@ -604,6 +604,9 @@