diff --git a/app/code/Magento/Config/Model/Config/Backend/File/Pdf.php b/app/code/Magento/Config/Model/Config/Backend/File/Pdf.php
new file mode 100644
index 0000000000000..8716fe5a23ad3
--- /dev/null
+++ b/app/code/Magento/Config/Model/Config/Backend/File/Pdf.php
@@ -0,0 +1,21 @@
+
- */
namespace Magento\Config\Model\Config\Backend\Image;
/**
+ * System config PDF field backend model.
+ *
* @api
* @since 100.0.2
+ * @see \Magento\Config\Model\Config\Backend\File\Pdf
*/
class Pdf extends \Magento\Config\Model\Config\Backend\Image
{
/**
+ * Returns the list of allowed file extensions.
+ *
* @return string[]
*/
protected function _getAllowedExtensions()
{
- return ['tif', 'tiff', 'png', 'jpg', 'jpe', 'jpeg'];
+ return ['tif', 'tiff', 'png', 'jpg', 'jpe', 'jpeg', 'pdf'];
}
}
diff --git a/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml b/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml
index 543aea7d8297f..20b62ef060309 100644
--- a/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml
+++ b/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml
@@ -14,5 +14,6 @@
+
diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/SelectAllDownloadableLinksDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/SelectAllDownloadableLinksDownloadableProductTest.xml
new file mode 100644
index 0000000000000..94940f0e08195
--- /dev/null
+++ b/app/code/Magento/Downloadable/Test/Mftf/Test/SelectAllDownloadableLinksDownloadableProductTest.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/SalesRule/Model/Rule/Action/SimpleActionOptionsProvider.php b/app/code/Magento/SalesRule/Model/Rule/Action/SimpleActionOptionsProvider.php
new file mode 100644
index 0000000000000..a0fd4bf576f61
--- /dev/null
+++ b/app/code/Magento/SalesRule/Model/Rule/Action/SimpleActionOptionsProvider.php
@@ -0,0 +1,30 @@
+ __('Percent of product price discount'), 'value' => Rule::BY_PERCENT_ACTION],
+ ['label' => __('Fixed amount discount'), 'value' => Rule::BY_FIXED_ACTION],
+ ['label' => __('Fixed amount discount for whole cart'), 'value' => Rule::CART_FIXED_ACTION],
+ ['label' => __('Buy X get Y free (discount amount is Y)'), 'value' => Rule::BUY_X_GET_Y_ACTION]
+ ];
+ }
+}
diff --git a/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php b/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php
index fdd6c2b169a7d..e4aaaec98dc79 100644
--- a/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php
+++ b/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php
@@ -5,11 +5,14 @@
*/
namespace Magento\SalesRule\Model\Rule\Metadata;
-use Magento\SalesRule\Model\Rule;
-use Magento\Store\Model\System\Store;
use Magento\Customer\Api\GroupRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\Convert\DataObject;
+use Magento\SalesRule\Model\Rule;
+use Magento\SalesRule\Model\Rule\Action\SimpleActionOptionsProvider;
+use Magento\SalesRule\Model\RuleFactory;
+use Magento\Store\Model\System\Store;
/**
* Metadata provider for sales rule edit form.
@@ -37,10 +40,15 @@ class ValueProvider
protected $objectConverter;
/**
- * @var \Magento\SalesRule\Model\RuleFactory
+ * @var RuleFactory
*/
protected $salesRuleFactory;
+ /**
+ * @var SimpleActionOptionsProvider
+ */
+ private $simpleActionOptionsProvider;
+
/**
* Initialize dependencies.
*
@@ -48,20 +56,24 @@ class ValueProvider
* @param GroupRepositoryInterface $groupRepository
* @param SearchCriteriaBuilder $searchCriteriaBuilder
* @param DataObject $objectConverter
- * @param \Magento\SalesRule\Model\RuleFactory $salesRuleFactory
+ * @param RuleFactory $salesRuleFactory
+ * @param SimpleActionOptionsProvider|null $simpleActionOptionsProvider
*/
public function __construct(
Store $store,
GroupRepositoryInterface $groupRepository,
SearchCriteriaBuilder $searchCriteriaBuilder,
DataObject $objectConverter,
- \Magento\SalesRule\Model\RuleFactory $salesRuleFactory
+ RuleFactory $salesRuleFactory,
+ SimpleActionOptionsProvider $simpleActionOptionsProvider = null
) {
$this->store = $store;
$this->groupRepository = $groupRepository;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->objectConverter = $objectConverter;
$this->salesRuleFactory = $salesRuleFactory;
+ $this->simpleActionOptionsProvider = $simpleActionOptionsProvider ?:
+ ObjectManager::getInstance()->get(SimpleActionOptionsProvider::class);
}
/**
@@ -71,15 +83,10 @@ public function __construct(
* @return array
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
- public function getMetadataValues(\Magento\SalesRule\Model\Rule $rule)
+ public function getMetadataValues(Rule $rule)
{
$customerGroups = $this->groupRepository->getList($this->searchCriteriaBuilder->create())->getItems();
- $applyOptions = [
- ['label' => __('Percent of product price discount'), 'value' => Rule::BY_PERCENT_ACTION],
- ['label' => __('Fixed amount discount'), 'value' => Rule::BY_FIXED_ACTION],
- ['label' => __('Fixed amount discount for whole cart'), 'value' => Rule::CART_FIXED_ACTION],
- ['label' => __('Buy X get Y free (discount amount is Y)'), 'value' => Rule::BUY_X_GET_Y_ACTION]
- ];
+ $applyOptions = $this->simpleActionOptionsProvider->toOptionArray();
$couponTypesOptions = [];
$couponTypes = $this->salesRuleFactory->create()->getCouponTypes();
diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Action/SimpleActionOptionsProviderTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Action/SimpleActionOptionsProviderTest.php
new file mode 100644
index 0000000000000..f1653dd043b50
--- /dev/null
+++ b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Action/SimpleActionOptionsProviderTest.php
@@ -0,0 +1,43 @@
+model = $objectManager->getObject(SimpleActionOptionsProvider::class);
+ }
+
+ public function testToOptionArray()
+ {
+ $expected = [
+ ['label' => __('Percent of product price discount'), 'value' => Rule::BY_PERCENT_ACTION],
+ ['label' => __('Fixed amount discount'), 'value' => Rule::BY_FIXED_ACTION],
+ ['label' => __('Fixed amount discount for whole cart'), 'value' => Rule::CART_FIXED_ACTION],
+ ['label' => __('Buy X get Y free (discount amount is Y)'), 'value' => Rule::BUY_X_GET_Y_ACTION]
+ ];
+
+ $this->assertEquals($expected, $this->model->toOptionArray());
+ }
+}
diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/ValueProviderTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/ValueProviderTest.php
index 0864b4a5e1480..d63ba150f4822 100644
--- a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/ValueProviderTest.php
+++ b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/ValueProviderTest.php
@@ -5,52 +5,72 @@
*/
namespace Magento\SalesRule\Test\Unit\Model\Rule\Metadata;
+use Magento\Customer\Api\Data\GroupInterface;
+use Magento\Customer\Api\Data\GroupSearchResultsInterface;
+use Magento\Customer\Api\GroupRepositoryInterface;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Convert\DataObject;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\SalesRule\Model\Rule;
+use Magento\SalesRule\Model\Rule\Action\SimpleActionOptionsProvider;
+use Magento\SalesRule\Model\Rule\Metadata\ValueProvider;
+use Magento\SalesRule\Model\RuleFactory;
+use Magento\Store\Model\System\Store;
+use PHPUnit\Framework\TestCase;
+use PHPUnit\Framework\MockObject\MockObject;
/**
* @covers Magento\SalesRule\Model\Rule\Metadata\ValueProvider
*/
-class ValueProviderTest extends \PHPUnit\Framework\TestCase
+class ValueProviderTest extends TestCase
{
/**
- * @var \Magento\SalesRule\Model\Rule\Metadata\ValueProvider
+ * @var ValueProvider
*/
protected $model;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var Store|MockObject
*/
protected $storeMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var GroupRepositoryInterface|MockObject
*/
protected $groupRepositoryMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var SearchCriteriaBuilder|MockObject
*/
protected $searchCriteriaBuilderMock;
/**
- * @var \PHPUnit_Framework_MockObject_MockObject
+ * @var DataObject|MockObject
*/
protected $dataObjectMock;
/**
- * @var \Magento\SalesRule\Model\RuleFactory|\PHPUnit_Framework_MockObject_MockObject
+ * @var RuleFactory|MockObject
*/
protected $ruleFactoryMock;
+ /**
+ * @var SimpleActionOptionsProvider|MockObject
+ */
+ private $simpleActionOptionsProviderMock;
+
protected function setUp()
{
- $this->searchCriteriaBuilderMock = $this->createMock(\Magento\Framework\Api\SearchCriteriaBuilder::class);
- $this->storeMock = $this->createMock(\Magento\Store\Model\System\Store::class);
- $this->groupRepositoryMock = $this->createMock(\Magento\Customer\Api\GroupRepositoryInterface::class);
- $this->dataObjectMock = $this->createMock(\Magento\Framework\Convert\DataObject::class);
- $searchCriteriaMock = $this->createMock(\Magento\Framework\Api\SearchCriteriaInterface::class);
- $groupSearchResultsMock = $this->createMock(\Magento\Customer\Api\Data\GroupSearchResultsInterface::class);
- $groupsMock = $this->createMock(\Magento\Customer\Api\Data\GroupInterface::class);
+ $expectedData = include __DIR__ . '/_files/MetaData.php';
+ $this->searchCriteriaBuilderMock = $this->createMock(SearchCriteriaBuilder::class);
+ $this->storeMock = $this->createMock(Store::class);
+ $this->groupRepositoryMock = $this->createMock(GroupRepositoryInterface::class);
+ $this->dataObjectMock = $this->createMock(DataObject::class);
+ $this->simpleActionOptionsProviderMock = $this->createMock(SimpleActionOptionsProvider::class);
+ $searchCriteriaMock = $this->createMock(SearchCriteriaInterface::class);
+ $groupSearchResultsMock = $this->createMock(GroupSearchResultsInterface::class);
+ $groupsMock = $this->createMock(GroupInterface::class);
$this->searchCriteriaBuilderMock->expects($this->once())->method('create')->willReturn($searchCriteriaMock);
$this->groupRepositoryMock->expects($this->once())->method('getList')->with($searchCriteriaMock)
@@ -59,15 +79,19 @@ protected function setUp()
$this->storeMock->expects($this->once())->method('getWebsiteValuesForForm')->willReturn([]);
$this->dataObjectMock->expects($this->once())->method('toOptionArray')->with([$groupsMock], 'id', 'code')
->willReturn([]);
- $this->ruleFactoryMock = $this->createPartialMock(\Magento\SalesRule\Model\RuleFactory::class, ['create']);
+ $this->ruleFactoryMock = $this->createPartialMock(RuleFactory::class, ['create']);
+ $this->simpleActionOptionsProviderMock->method('toOptionArray')->willReturn(
+ $expectedData['actions']['children']['simple_action']['arguments']['data']['config']['options']
+ );
$this->model = (new ObjectManager($this))->getObject(
- \Magento\SalesRule\Model\Rule\Metadata\ValueProvider::class,
+ ValueProvider::class,
[
'store' => $this->storeMock,
'groupRepository' => $this->groupRepositoryMock,
'searchCriteriaBuilder' => $this->searchCriteriaBuilderMock,
'objectConverter' => $this->dataObjectMock,
'salesRuleFactory' => $this->ruleFactoryMock,
+ 'simpleActionOptionsProvider' => $this->simpleActionOptionsProviderMock
]
);
}
@@ -76,8 +100,8 @@ public function testGetMetadataValues()
{
$expectedData = include __DIR__ . '/_files/MetaData.php';
- /** @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleMock */
- $ruleMock = $this->createMock(\Magento\SalesRule\Model\Rule::class);
+ /** @var Rule|MockObject $ruleMock */
+ $ruleMock = $this->createMock(Rule::class);
$this->ruleFactoryMock->expects($this->once())
->method('create')
->willReturn($ruleMock);
diff --git a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js
index 033e2e43a3c22..aca843872af65 100644
--- a/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js
+++ b/app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js
@@ -79,7 +79,9 @@ define([
$(element).is('textarea') ||
$('#' + element.id + ' option:selected').length
) {
- dataToAdd = $.extend({}, dataToAdd, self._getElementData(element));
+ if ($(element).data('selector') || $(element).attr('name')) {
+ dataToAdd = $.extend({}, dataToAdd, self._getElementData(element));
+ }
return;
}
diff --git a/lib/internal/Magento/Framework/App/ProductMetadata.php b/lib/internal/Magento/Framework/App/ProductMetadata.php
index c9fde94352a71..631dba8273bcd 100644
--- a/lib/internal/Magento/Framework/App/ProductMetadata.php
+++ b/lib/internal/Magento/Framework/App/ProductMetadata.php
@@ -8,12 +8,13 @@
namespace Magento\Framework\App;
use Magento\Framework\Composer\ComposerFactory;
-use \Magento\Framework\Composer\ComposerJsonFinder;
-use \Magento\Framework\App\Filesystem\DirectoryList;
-use \Magento\Framework\Composer\ComposerInformation;
+use Magento\Framework\Composer\ComposerJsonFinder;
+use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Composer\ComposerInformation;
/**
* Class ProductMetadata
+ *
* @package Magento\Framework\App
*/
class ProductMetadata implements ProductMetadataInterface
@@ -28,6 +29,11 @@ class ProductMetadata implements ProductMetadataInterface
*/
const PRODUCT_NAME = 'Magento';
+ /**
+ * Cache key for Magento product version
+ */
+ private const MAGENTO_PRODUCT_VERSION_CACHE_KEY = 'magento-product-version';
+
/**
* Product version
*
@@ -46,12 +52,19 @@ class ProductMetadata implements ProductMetadataInterface
*/
private $composerInformation;
+ /**
+ * @var CacheInterface
+ */
+ private $cache;
+
/**
* @param ComposerJsonFinder $composerJsonFinder
+ * @param CacheInterface|null $cache
*/
- public function __construct(ComposerJsonFinder $composerJsonFinder)
+ public function __construct(ComposerJsonFinder $composerJsonFinder, CacheInterface $cache = null)
{
$this->composerJsonFinder = $composerJsonFinder;
+ $this->cache = $cache ?: ObjectManager::getInstance()->get(CacheInterface::class);
}
/**
@@ -61,6 +74,9 @@ public function __construct(ComposerJsonFinder $composerJsonFinder)
*/
public function getVersion()
{
+ if ($cachedVersion = $this->cache->load(self::MAGENTO_PRODUCT_VERSION_CACHE_KEY)) {
+ $this->version = $cachedVersion;
+ }
if (!$this->version) {
if (!($this->version = $this->getSystemPackageVersion())) {
if ($this->getComposerInformation()->isMagentoRoot()) {
@@ -69,6 +85,7 @@ public function getVersion()
$this->version = 'UNKNOWN';
}
}
+ $this->cache->save($this->version, self::MAGENTO_PRODUCT_VERSION_CACHE_KEY);
}
return $this->version;
}
diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js
index 55921c054e61a..2ec39efcc283e 100644
--- a/lib/web/mage/validation.js
+++ b/lib/web/mage/validation.js
@@ -559,7 +559,7 @@
/* eslint-enable max-len */
'pattern': [
function (value, element, param) {
- return this.optional(element) || param.test(value);
+ return this.optional(element) || new RegExp(param).test(value);
},
$.mage.__('Invalid format.')
],