diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
index 72fd8c3a63f..bb81f9ebb47 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
@@ -61,6 +61,7 @@ class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implemen
* @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $resultMethodFactory
* @param \Magento\OfflineShipping\Model\ResourceModel\Carrier\TablerateFactory $tablerateFactory
* @param array $data
+ * @throws LocalizedException
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
public function __construct(
diff --git a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/CSV/RowParser.php b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/CSV/RowParser.php
index 9431973fdfe..f7b487d37bf 100644
--- a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/CSV/RowParser.php
+++ b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/CSV/RowParser.php
@@ -9,6 +9,9 @@
use Magento\Framework\Phrase;
use Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate\LocationDirectory;
+/**
+ * Row parser.
+ */
class RowParser
{
/**
@@ -26,6 +29,8 @@ public function __construct(LocationDirectory $locationDirectory)
}
/**
+ * Retrieve columns.
+ *
* @return array
*/
public function getColumns()
@@ -42,6 +47,8 @@ public function getColumns()
}
/**
+ * Parse provided row data.
+ *
* @param array $rowData
* @param int $rowNumber
* @param int $websiteId
@@ -71,23 +78,30 @@ public function parse(
}
$countryId = $this->getCountryId($rowData, $rowNumber, $columnResolver);
- $regionId = $this->getRegionId($rowData, $rowNumber, $columnResolver, $countryId);
+ $regionIds = $this->getRegionIds($rowData, $rowNumber, $columnResolver, $countryId);
$zipCode = $this->getZipCode($rowData, $columnResolver);
$conditionValue = $this->getConditionValue($rowData, $rowNumber, $conditionFullName, $columnResolver);
$price = $this->getPrice($rowData, $rowNumber, $columnResolver);
- return [
- 'website_id' => $websiteId,
- 'dest_country_id' => $countryId,
- 'dest_region_id' => $regionId,
- 'dest_zip' => $zipCode,
- 'condition_name' => $conditionShortName,
- 'condition_value' => $conditionValue,
- 'price' => $price,
- ];
+ $rates = [];
+ foreach ($regionIds as $regionId) {
+ $rates[] = [
+ 'website_id' => $websiteId,
+ 'dest_country_id' => $countryId,
+ 'dest_region_id' => $regionId,
+ 'dest_zip' => $zipCode,
+ 'condition_name' => $conditionShortName,
+ 'condition_value' => $conditionValue,
+ 'price' => $price,
+ ];
+ }
+
+ return $rates;
}
/**
+ * Get country id from provided row data.
+ *
* @param array $rowData
* @param int $rowNumber
* @param ColumnResolver $columnResolver
@@ -116,21 +130,23 @@ private function getCountryId(array $rowData, $rowNumber, ColumnResolver $column
}
/**
+ * Retrieve region id from provided row data.
+ *
* @param array $rowData
* @param int $rowNumber
* @param ColumnResolver $columnResolver
* @param int $countryId
- * @return int|string
+ * @return array
* @throws ColumnNotFoundException
* @throws RowException
*/
- private function getRegionId(array $rowData, $rowNumber, ColumnResolver $columnResolver, $countryId)
+ private function getRegionIds(array $rowData, $rowNumber, ColumnResolver $columnResolver, $countryId)
{
$regionCode = $columnResolver->getColumnValue(ColumnResolver::COLUMN_REGION, $rowData);
if ($countryId !== '0' && $this->locationDirectory->hasRegionId($countryId, $regionCode)) {
- $regionId = $this->locationDirectory->getRegionId($countryId, $regionCode);
+ $regionIds = $this->locationDirectory->getRegionIds($countryId, $regionCode);
} elseif ($regionCode === '*' || $regionCode === '') {
- $regionId = 0;
+ $regionIds = [0];
} else {
throw new RowException(
__(
@@ -141,10 +157,12 @@ private function getRegionId(array $rowData, $rowNumber, ColumnResolver $columnR
)
);
}
- return $regionId;
+ return $regionIds;
}
/**
+ * Retrieve zip code from provided row data.
+ *
* @param array $rowData
* @param ColumnResolver $columnResolver
* @return float|int|null|string
@@ -160,6 +178,8 @@ private function getZipCode(array $rowData, ColumnResolver $columnResolver)
}
/**
+ * Get condition value form provided row data.
+ *
* @param array $rowData
* @param int $rowNumber
* @param string $conditionFullName
@@ -187,6 +207,8 @@ private function getConditionValue(array $rowData, $rowNumber, $conditionFullNam
}
/**
+ * Retrieve price from provided row data.
+ *
* @param array $rowData
* @param int $rowNumber
* @param ColumnResolver $columnResolver
@@ -212,6 +234,7 @@ private function getPrice(array $rowData, $rowNumber, ColumnResolver $columnReso
/**
* Parse and validate positive decimal value
+ *
* Return false if value is not decimal or is not positive
*
* @param string $value
diff --git a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/Import.php b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/Import.php
index a5b0d7e87d2..7735f8ce899 100644
--- a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/Import.php
+++ b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/Import.php
@@ -17,6 +17,7 @@
use Magento\Store\Model\StoreManagerInterface;
/**
+ * Import offline shipping.
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Import
@@ -87,6 +88,8 @@ public function __construct(
}
/**
+ * Check if there are errors.
+ *
* @return bool
*/
public function hasErrors()
@@ -95,6 +98,8 @@ public function hasErrors()
}
/**
+ * Get errors.
+ *
* @return array
*/
public function getErrors()
@@ -103,6 +108,8 @@ public function getErrors()
}
/**
+ * Retrieve columns.
+ *
* @return array
*/
public function getColumns()
@@ -111,6 +118,8 @@ public function getColumns()
}
/**
+ * Get data from file.
+ *
* @param ReadInterface $file
* @param int $websiteId
* @param string $conditionShortName
@@ -135,7 +144,7 @@ public function getData(ReadInterface $file, $websiteId, $conditionShortName, $c
if (empty($csvLine)) {
continue;
}
- $rowData = $this->rowParser->parse(
+ $rowsData = $this->rowParser->parse(
$csvLine,
$rowNumber,
$websiteId,
@@ -144,20 +153,25 @@ public function getData(ReadInterface $file, $websiteId, $conditionShortName, $c
$columnResolver
);
- // protect from duplicate
- $hash = $this->dataHashGenerator->getHash($rowData);
- if (array_key_exists($hash, $this->uniqueHash)) {
- throw new RowException(
- __(
- 'Duplicate Row #%1 (duplicates row #%2)',
- $rowNumber,
- $this->uniqueHash[$hash]
- )
- );
+ foreach ($rowsData as $rowData) {
+ // protect from duplicate
+ $hash = $this->dataHashGenerator->getHash($rowData);
+ if (array_key_exists($hash, $this->uniqueHash)) {
+ throw new RowException(
+ __(
+ 'Duplicate Row #%1 (duplicates row #%2)',
+ $rowNumber,
+ $this->uniqueHash[$hash]
+ )
+ );
+ }
+ $this->uniqueHash[$hash] = $rowNumber;
+
+ $items[] = $rowData;
+ }
+ if (count($rowsData) > 1) {
+ $bunchSize += count($rowsData) - 1;
}
- $this->uniqueHash[$hash] = $rowNumber;
-
- $items[] = $rowData;
if (count($items) === $bunchSize) {
yield $items;
$items = [];
@@ -172,6 +186,8 @@ public function getData(ReadInterface $file, $websiteId, $conditionShortName, $c
}
/**
+ * Retrieve column headers.
+ *
* @param ReadInterface $file
* @return array|bool
* @throws LocalizedException
diff --git a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/LocationDirectory.php b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/LocationDirectory.php
index 1a311f3658a..e015f7b5463 100644
--- a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/LocationDirectory.php
+++ b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/LocationDirectory.php
@@ -6,6 +6,9 @@
namespace Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate;
+/**
+ * Location directory.
+ */
class LocationDirectory
{
/**
@@ -13,6 +16,11 @@ class LocationDirectory
*/
protected $regions;
+ /**
+ * @var array
+ */
+ private $regionsByCode;
+
/**
* @var array
*/
@@ -47,6 +55,8 @@ public function __construct(
}
/**
+ * Retrieve country id.
+ *
* @param string $countryCode
* @return null|string
*/
@@ -88,6 +98,8 @@ protected function loadCountries()
}
/**
+ * Check if there is country id with provided country code.
+ *
* @param string $countryCode
* @return bool
*/
@@ -98,6 +110,8 @@ public function hasCountryId($countryCode)
}
/**
+ * Check if there is region id with provided region code and country id.
+ *
* @param string $countryId
* @param string $regionCode
* @return bool
@@ -115,29 +129,50 @@ public function hasRegionId($countryId, $regionCode)
*/
protected function loadRegions()
{
- if ($this->regions !== null) {
+ if ($this->regions !== null && $this->regionsByCode !== null) {
return $this;
}
$this->regions = [];
+ $this->regionsByCode = [];
/** @var $collection \Magento\Directory\Model\ResourceModel\Region\Collection */
$collection = $this->_regionCollectionFactory->create();
foreach ($collection->getData() as $row) {
$this->regions[$row['country_id']][$row['code']] = (int)$row['region_id'];
+ if (empty($this->regionsByCode[$row['country_id']][$row['code']])) {
+ $this->regionsByCode[$row['country_id']][$row['code']] = [];
+ }
+ $this->regionsByCode[$row['country_id']][$row['code']][] = (int)$row['region_id'];
}
return $this;
}
/**
+ * Retrieve region id.
+ *
* @param int $countryId
* @param string $regionCode
* @return string
+ * @deprecated
*/
public function getRegionId($countryId, $regionCode)
{
$this->loadRegions();
return $this->regions[$countryId][$regionCode];
}
+
+ /**
+ * Return region ids for country and region
+ *
+ * @param int $countryId
+ * @param string $regionCode
+ * @return array
+ */
+ public function getRegionIds($countryId, $regionCode)
+ {
+ $this->loadRegions();
+ return $this->regionsByCode[$countryId][$regionCode];
+ }
}
diff --git a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php
index 5b03ef0cb02..f7105b8e547 100644
--- a/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php
+++ b/app/code/Magento/OfflineShipping/Model/ResourceModel/Carrier/Tablerate/RateQuery.php
@@ -6,6 +6,9 @@
namespace Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate;
+/**
+ * Query builder for table rate
+ */
class RateQuery
{
/**
@@ -24,6 +27,8 @@ public function __construct(
}
/**
+ * Prepare select
+ *
* @param \Magento\Framework\DB\Select $select
* @return \Magento\Framework\DB\Select
*/
@@ -42,6 +47,7 @@ public function prepareSelect(\Magento\Framework\DB\Select $select)
') OR (',
[
"dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = :postcode",
+ "dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = :postcode_prefix",
"dest_country_id = :country_id AND dest_region_id = :region_id AND dest_zip = ''",
// Handle asterisk in dest_zip field
@@ -51,7 +57,7 @@ public function prepareSelect(\Magento\Framework\DB\Select $select)
"dest_country_id = '0' AND dest_region_id = 0 AND dest_zip = '*'",
"dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = ''",
"dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = :postcode",
- "dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = '*'"
+ "dest_country_id = :country_id AND dest_region_id = 0 AND dest_zip = :postcode_prefix"
]
) . ')';
$select->where($orWhere);
@@ -76,6 +82,8 @@ public function prepareSelect(\Magento\Framework\DB\Select $select)
}
/**
+ * Returns query bindings
+ *
* @return array
*/
public function getBindings()
@@ -85,6 +93,7 @@ public function getBindings()
':country_id' => $this->request->getDestCountryId(),
':region_id' => (int)$this->request->getDestRegionId(),
':postcode' => $this->request->getDestPostcode(),
+ ':postcode_prefix' => $this->getDestPostcodePrefix()
];
// Render condition by condition name
@@ -106,10 +115,26 @@ public function getBindings()
}
/**
+ * Returns rate request
+ *
* @return \Magento\Quote\Model\Quote\Address\RateRequest
*/
public function getRequest()
{
return $this->request;
}
+
+ /**
+ * Returns the entire postcode if it contains no dash or the part of it prior to the dash in the other case
+ *
+ * @return string
+ */
+ private function getDestPostcodePrefix()
+ {
+ if (!preg_match("/^(.+)-(.+)$/", $this->request->getDestPostcode(), $zipParts)) {
+ return $this->request->getDestPostcode();
+ }
+
+ return $zipParts[1];
+ }
}
diff --git a/app/code/Magento/OfflineShipping/Test/Unit/Model/ResourceModel/Carrier/Tablerate/CSV/RowParserTest.php b/app/code/Magento/OfflineShipping/Test/Unit/Model/ResourceModel/Carrier/Tablerate/CSV/RowParserTest.php
index 8c34e9a0d65..683790c5312 100644
--- a/app/code/Magento/OfflineShipping/Test/Unit/Model/ResourceModel/Carrier/Tablerate/CSV/RowParserTest.php
+++ b/app/code/Magento/OfflineShipping/Test/Unit/Model/ResourceModel/Carrier/Tablerate/CSV/RowParserTest.php
@@ -37,7 +37,7 @@ class RowParserTest extends \PHPUnit\Framework\TestCase
protected function setUp()
{
$this->locationDirectoryMock = $this->getMockBuilder(LocationDirectory::class)
- ->setMethods(['hasCountryId', 'getCountryId', 'hasRegionId', 'getRegionId'])
+ ->setMethods(['hasCountryId', 'getCountryId', 'hasRegionId', 'getRegionIds'])
->disableOriginalConstructor()
->getMock();
$this->columnResolverMock = $this->getMockBuilder(ColumnResolver::class)
@@ -92,7 +92,7 @@ public function testParse()
$conditionShortName,
$columnValueMap
);
- $this->assertEquals($expectedResult, $result);
+ $this->assertEquals([$expectedResult], $result);
}
/**
diff --git a/app/code/Magento/OfflineShipping/Test/Unit/Model/ResourceModel/Carrier/Tablerate/ImportTest.php b/app/code/Magento/OfflineShipping/Test/Unit/Model/ResourceModel/Carrier/Tablerate/ImportTest.php
index 4e433c380f7..722683decb4 100644
--- a/app/code/Magento/OfflineShipping/Test/Unit/Model/ResourceModel/Carrier/Tablerate/ImportTest.php
+++ b/app/code/Magento/OfflineShipping/Test/Unit/Model/ResourceModel/Carrier/Tablerate/ImportTest.php
@@ -77,9 +77,6 @@ protected function setUp()
->getMock();
$this->dataHashGeneratorMock = $this->getMockBuilder(DataHashGenerator::class)
->getMock();
- $this->rowParserMock->expects($this->any())
- ->method('parse')
- ->willReturnArgument(0);
$this->dataHashGeneratorMock->expects($this->any())
->method('getHash')
->willReturnCallback(
@@ -124,6 +121,15 @@ public function testGetData()
['a4', 'b4', 'c4', 'd4', 'e4'],
['a5', 'b5', 'c5', 'd5', 'e5'],
];
+ $this->rowParserMock->expects($this->any())
+ ->method('parse')
+ ->willReturn(
+ [['a1', 'b1', 'c1', 'd1', 'e1']],
+ [['a2', 'b2', 'c2', 'd2', 'e2']],
+ [['a3', 'b3', 'c3', 'd3', 'e3']],
+ [['a4', 'b4', 'c4', 'd4', 'e4']],
+ [['a5', 'b5', 'c5', 'd5', 'e5']]
+ );
$file = $this->createFileMock($lines);
$expectedResult = [
[
@@ -167,6 +173,13 @@ public function testGetDataWithDuplicatedLine()
[],
['a2', 'b2', 'c2', 'd2', 'e2'],
];
+ $this->rowParserMock->expects($this->any())
+ ->method('parse')
+ ->willReturn(
+ [['a1', 'b1', 'c1', 'd1', 'e1']],
+ [['a1', 'b1', 'c1', 'd1', 'e1']],
+ [['a2', 'b2', 'c2', 'd2', 'e2']]
+ );
$file = $this->createFileMock($lines);
$expectedResult = [
[
diff --git a/app/code/Magento/PageCache/Model/System/Config/Backend/AccessList.php b/app/code/Magento/PageCache/Model/System/Config/Backend/AccessList.php
new file mode 100644
index 00000000000..e16584b0b17
--- /dev/null
+++ b/app/code/Magento/PageCache/Model/System/Config/Backend/AccessList.php
@@ -0,0 +1,37 @@
+getValue();
+ if (!is_string($value) || !preg_match('/^[\w\s\.\-\,\:]+$/', $value)) {
+ throw new LocalizedException(
+ new Phrase(
+ 'Access List value "%1" is not valid. '
+ .'Please use only IP addresses and host names.',
+ [$value]
+ )
+ );
+ }
+ }
+}
diff --git a/app/code/Magento/PageCache/Test/Unit/Model/System/Config/Backend/AccessListTest.php b/app/code/Magento/PageCache/Test/Unit/Model/System/Config/Backend/AccessListTest.php
new file mode 100644
index 00000000000..e84b412beb8
--- /dev/null
+++ b/app/code/Magento/PageCache/Test/Unit/Model/System/Config/Backend/AccessListTest.php
@@ -0,0 +1,92 @@
+getMockForAbstractClass(
+ ScopeConfigInterface::class
+ );
+ $configMock->expects($this->any())
+ ->method('getValue')
+ ->with('system/full_page_cache/default')
+ ->willReturn(['access_list' => 'localhost']);
+ $this->accessList = $objectManager->getObject(
+ AccessList::class,
+ [
+ 'config' => $configMock,
+ 'data' => ['field' => 'access_list']
+ ]
+ );
+ }
+
+ /**
+ * @return array
+ */
+ public function getValidValues(): array
+ {
+ return [
+ ['localhost', 'localhost'],
+ [null, 'localhost'],
+ ['127.0.0.1', '127.0.0.1'],
+ ['127.0.0.1, localhost, ::2', '127.0.0.1, localhost, ::2'],
+ ];
+ }
+
+ /**
+ * @param mixed $value
+ * @param mixed $expectedValue
+ * @dataProvider getValidValues
+ */
+ public function testBeforeSave($value, $expectedValue)
+ {
+ $this->accessList->setValue($value);
+ $this->accessList->beforeSave();
+ $this->assertEquals($expectedValue, $this->accessList->getValue());
+ }
+
+ /**
+ * @return array
+ */
+ public function getInvalidValues(): array
+ {
+ return [
+ ['\\bull val\\'],
+ ['{*I am not an IP*}'],
+ ['{*I am not an IP*}, 127.0.0.1'],
+ ];
+ }
+
+ /**
+ * @param mixed $value
+ * @expectedException \Magento\Framework\Exception\LocalizedException
+ * @dataProvider getInvalidValues
+ */
+ public function testBeforeSaveInvalid($value)
+ {
+ $this->accessList->setValue($value);
+ $this->accessList->beforeSave();
+ }
+}
diff --git a/app/code/Magento/PageCache/etc/adminhtml/system.xml b/app/code/Magento/PageCache/etc/adminhtml/system.xml
index 5055b179568..2a4439ac6a9 100644
--- a/app/code/Magento/PageCache/etc/adminhtml/system.xml
+++ b/app/code/Magento/PageCache/etc/adminhtml/system.xml
@@ -20,7 +20,7 @@
IPs access list separated with ',' that can purge Varnish configuration for config file generation.
If field is empty default value localhost will be saved.
-
Magento\PageCache\Model\System\Config\Backend\Varnish
+
Magento\PageCache\Model\System\Config\Backend\AccessList
1
diff --git a/app/code/Magento/Payment/etc/config.xml b/app/code/Magento/Payment/etc/config.xml
index 9fe859c96a9..663734fb066 100644
--- a/app/code/Magento/Payment/etc/config.xml
+++ b/app/code/Magento/Payment/etc/config.xml
@@ -13,6 +13,7 @@
Magento\Payment\Model\Method\Free
pending
No Payment Information Required
+
authorize
0
1
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Index.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Index.php
index b4c68df6e29..ca92b6a044f 100644
--- a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Index.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Paypal\Controller\Adminhtml\Billing\Agreement;
-class Index extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Index.php b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Index.php
index 91f3e8d9065..c2cee0ffbc6 100644
--- a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Index.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Paypal\Controller\Adminhtml\Paypal\Reports;
-class Index extends \Magento\Paypal\Controller\Adminhtml\Paypal\Reports
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\Paypal\Controller\Adminhtml\Paypal\Reports implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Paypal/Controller/Express/GetToken.php b/app/code/Magento/Paypal/Controller/Express/GetToken.php
index 7c127803cb0..93e9abb4c09 100644
--- a/app/code/Magento/Paypal/Controller/Express/GetToken.php
+++ b/app/code/Magento/Paypal/Controller/Express/GetToken.php
@@ -5,6 +5,7 @@
*/
namespace Magento\Paypal\Controller\Express;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Checkout\Helper\Data;
use Magento\Checkout\Helper\ExpressRedirect;
use Magento\Checkout\Model\Type\Onepage;
@@ -19,7 +20,7 @@
* Class GetToken
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class GetToken extends AbstractExpress
+class GetToken extends AbstractExpress implements HttpGetActionInterface
{
/**
* Config mode type
diff --git a/app/code/Magento/Paypal/Controller/Express/Start.php b/app/code/Magento/Paypal/Controller/Express/Start.php
index e0a3c5381be..b381c413071 100644
--- a/app/code/Magento/Paypal/Controller/Express/Start.php
+++ b/app/code/Magento/Paypal/Controller/Express/Start.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Paypal\Controller\Express;
-class Start extends \Magento\Paypal\Controller\Express\AbstractExpress\Start
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Start extends \Magento\Paypal\Controller\Express\AbstractExpress\Start implements HttpGetActionInterface
{
/**
* Config mode type
diff --git a/app/code/Magento/Paypal/Controller/Payflowexpress/Start.php b/app/code/Magento/Paypal/Controller/Payflowexpress/Start.php
index a6fbcfd0239..4615320c945 100644
--- a/app/code/Magento/Paypal/Controller/Payflowexpress/Start.php
+++ b/app/code/Magento/Paypal/Controller/Payflowexpress/Start.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Paypal\Controller\Payflowexpress;
-class Start extends \Magento\Paypal\Controller\Express\AbstractExpress\Start
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Start extends \Magento\Paypal\Controller\Express\AbstractExpress\Start implements HttpGetActionInterface
{
/**
* Config mode type
diff --git a/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php b/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php
index 2efae34a964..85907c9d371 100644
--- a/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php
+++ b/app/code/Magento/Paypal/Controller/Transparent/RequestSecureToken.php
@@ -5,6 +5,7 @@
*/
namespace Magento\Paypal\Controller\Transparent;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\Json;
use Magento\Framework\Controller\Result\JsonFactory;
@@ -21,7 +22,7 @@
* @package Magento\Paypal\Controller\Transparent
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class RequestSecureToken extends \Magento\Framework\App\Action\Action
+class RequestSecureToken extends \Magento\Framework\App\Action\Action implements HttpPostActionInterface
{
/**
* @var JsonFactory
diff --git a/app/code/Magento/Paypal/Model/AbstractConfig.php b/app/code/Magento/Paypal/Model/AbstractConfig.php
index 3b0f7b97482..e5beddac3b1 100644
--- a/app/code/Magento/Paypal/Model/AbstractConfig.php
+++ b/app/code/Magento/Paypal/Model/AbstractConfig.php
@@ -134,7 +134,7 @@ public function setStoreId($storeId)
* Returns payment configuration value
*
* @param string $key
- * @param null $storeId
+ * @param null|int $storeId
* @return null|string
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
@@ -224,15 +224,26 @@ protected function _prepareValue($key, $value)
*/
public function shouldUseUnilateralPayments()
{
- return $this->getValue('business_account') && !$this->isWppApiAvailabe();
+ return $this->getValue('business_account') && !$this->isWppApiAvailable();
}
/**
* Check whether WPP API credentials are available for this method
*
+ * @deprecated
* @return bool
*/
public function isWppApiAvailabe()
+ {
+ return $this->isWppApiAvailable();
+ }
+
+ /**
+ * Check whether WPP API credentials are available for this method
+ *
+ * @return bool
+ */
+ public function isWppApiAvailable()
{
return $this->getValue('api_username')
&& $this->getValue('api_password')
@@ -243,7 +254,7 @@ public function isWppApiAvailabe()
/**
* Check whether method available for checkout or not
*
- * @param null $methodCode
+ * @param null|string $methodCode
*
* @return bool
*/
diff --git a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
index 6373c6d99fb..b769cbe4364 100644
--- a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
+++ b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
@@ -136,6 +136,9 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
'CVV2MATCH' => 'cvv2_check_result',
'USERSELECTEDFUNDINGSOURCE' => 'funding_source',
+
+ 'NOSHIPPING' => 'suppress_shipping',
+ 'REQBILLINGADDRESS' => 'require_billing_address',
];
/**
@@ -248,6 +251,8 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
'PAYFLOWCOLOR',
'LOCALECODE',
'USERSELECTEDFUNDINGSOURCE',
+ 'NOSHIPPING',
+ 'REQBILLINGADDRESS',
];
/**
@@ -727,6 +732,7 @@ protected function _prepareExpressCheckoutCallRequest(&$requestFields)
/**
* Additional response processing.
+ *
* Hack to cut off length from API type response params.
*
* @param array $response
@@ -784,7 +790,8 @@ protected function _exportLineItems(array &$request, $i = 0)
}
/**
- * Set specific data when negative line item case
+ * Set specific data when negative line item case.
+ *
* @return void
*/
protected function _setSpecificForNegativeLineItems()
diff --git a/app/code/Magento/Paypal/Model/Config.php b/app/code/Magento/Paypal/Model/Config.php
index 34e40ac7509..b058ba129a3 100644
--- a/app/code/Magento/Paypal/Model/Config.php
+++ b/app/code/Magento/Paypal/Model/Config.php
@@ -10,6 +10,7 @@
/**
* Config model that is aware of all \Magento\Paypal payment methods
+ *
* Works with PayPal-specific system configuration
* @SuppressWarnings(PHPMD.ExcessivePublicCount)
@@ -632,6 +633,7 @@ public function __construct(
/**
* Check whether method available for checkout or not
+ *
* Logic based on merchant country, methods dependence
*
* @param string|null $methodCode
@@ -677,7 +679,7 @@ public function isMethodAvailable($methodCode = null)
}
break;
case self::METHOD_BILLING_AGREEMENT:
- $result = $this->isWppApiAvailabe();
+ $result = $this->isWppApiAvailable();
break;
}
return $result;
@@ -723,6 +725,7 @@ public function getMerchantCountry()
/**
* Check whether method supported for specified country or not
+ *
* Use $_methodCode and merchant country by default
*
* @param string|null $method
@@ -896,6 +899,7 @@ public function getExpressCheckoutEditUrl($token)
/**
* Get url for additional actions that PayPal may require customer to do after placing the order.
+ *
* For instance, redirecting customer to bank for payment confirmation.
*
* @param string $token
@@ -957,6 +961,7 @@ public function areButtonsDynamic()
/**
* Express checkout shortcut pic URL getter
+ *
* PayPal will ignore "pal", if there is no total amount specified
*
* @param string $localeCode
@@ -996,6 +1001,7 @@ public function getExpressCheckoutInContextImageUrl($localeCode)
/**
* Get PayPal "mark" image URL
+ *
* Supposed to be used on payment methods selection
* $staticSize is applicable for static images only
*
@@ -1032,6 +1038,7 @@ public function getPaymentMarkImageUrl($localeCode, $orderTotal = null, $pal = n
/**
* Get "What Is PayPal" localized URL
+ *
* Supposed to be used with "mark" as popup window
*
* @param \Magento\Framework\Locale\ResolverInterface $localeResolver
@@ -1262,6 +1269,7 @@ public function getExpressCheckoutBASignupOptions()
/**
* Whether to ask customer to create billing agreements
+ *
* Unilateral payments are incompatible with the billing agreements
*
* @return bool
@@ -1376,6 +1384,7 @@ public function exportExpressCheckoutStyleSettings(\Magento\Framework\DataObject
/**
* Dynamic PayPal image URL getter
+ *
* Also can render dynamic Acceptance Mark
*
* @param string $type
@@ -1725,6 +1734,7 @@ public function getBmlPublisherId()
/**
* Get Display option from stored config
+ *
* @param string $section
*
* @return mixed
@@ -1752,6 +1762,7 @@ public function getBmlDisplay($section)
/**
* Get Position option from stored config
+ *
* @param string $section
*
* @return mixed
@@ -1767,6 +1778,7 @@ public function getBmlPosition($section)
/**
* Get Size option from stored config
+ *
* @param string $section
*
* @return mixed
diff --git a/app/code/Magento/Paypal/Model/Express/Checkout.php b/app/code/Magento/Paypal/Model/Express/Checkout.php
index 1300c793689..856e01f7353 100644
--- a/app/code/Magento/Paypal/Model/Express/Checkout.php
+++ b/app/code/Magento/Paypal/Model/Express/Checkout.php
@@ -1056,10 +1056,7 @@ protected function _prepareShippingOptions(Address $address, $mayReturnEmpty = f
*/
protected static function cmpShippingOptions(DataObject $option1, DataObject $option2)
{
- if ($option1->getAmount() == $option2->getAmount()) {
- return 0;
- }
- return ($option1->getAmount() < $option2->getAmount()) ? -1 : 1;
+ return $option1->getAmount() <=> $option2->getAmount();
}
/**
diff --git a/app/code/Magento/Paypal/Test/Unit/Model/AbstractConfigTest.php b/app/code/Magento/Paypal/Test/Unit/Model/AbstractConfigTest.php
index 9ec93182126..78bd269403b 100644
--- a/app/code/Magento/Paypal/Test/Unit/Model/AbstractConfigTest.php
+++ b/app/code/Magento/Paypal/Test/Unit/Model/AbstractConfigTest.php
@@ -189,14 +189,14 @@ public function getValueDataProvider()
*
* @dataProvider isWppApiAvailabeDataProvider
*/
- public function testIsWppApiAvailabe($returnMap, $expectedValue)
+ public function testIsWppApiAvailable($returnMap, $expectedValue)
{
$this->config->setMethod('paypal_express');
$this->scopeConfigMock->expects($this->any())
->method('getValue')
->willReturnMap($returnMap);
- $this->assertEquals($expectedValue, $this->config->isWppApiAvailabe());
+ $this->assertEquals($expectedValue, $this->config->isWppApiAvailable());
}
/**
diff --git a/app/code/Magento/Paypal/etc/db_schema.xml b/app/code/Magento/Paypal/etc/db_schema.xml
index 2703ee4f5be..0441231e64a 100644
--- a/app/code/Magento/Paypal/etc/db_schema.xml
+++ b/app/code/Magento/Paypal/etc/db_schema.xml
@@ -134,7 +134,7 @@
+ comment="Entity ID"/>
diff --git a/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php b/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php
index 23721cb4b16..914b5fa2717 100644
--- a/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php
+++ b/app/code/Magento/ProductVideo/Controller/Adminhtml/Product/Gallery/RetrieveImage.php
@@ -6,6 +6,7 @@
namespace Magento\ProductVideo\Controller\Adminhtml\Product\Gallery;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\File\Uploader;
@@ -13,7 +14,7 @@
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class RetrieveImage extends \Magento\Backend\App\Action
+class RetrieveImage extends \Magento\Backend\App\Action implements HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/ProductVideo/i18n/de_DE.csv b/app/code/Magento/ProductVideo/i18n/de_DE.csv
index 70473173969..ca24668bb8d 100644
--- a/app/code/Magento/ProductVideo/i18n/de_DE.csv
+++ b/app/code/Magento/ProductVideo/i18n/de_DE.csv
@@ -7,3 +7,4 @@
"Preview Image","Preview Image"
"Get Video Information","Get Video Information"
"Youtube or Vimeo supported","Youtube or Vimeo supported"
+"Delete image in all store views","Delete image in all store views"
diff --git a/app/code/Magento/ProductVideo/i18n/en_US.csv b/app/code/Magento/ProductVideo/i18n/en_US.csv
index 2d226c6daef..debcab151cc 100644
--- a/app/code/Magento/ProductVideo/i18n/en_US.csv
+++ b/app/code/Magento/ProductVideo/i18n/en_US.csv
@@ -40,3 +40,4 @@ Delete,Delete
"Autostart base video","Autostart base video"
"Show related video","Show related video"
"Auto restart video","Auto restart video"
+"Delete image in all store views","Delete image in all store views"
diff --git a/app/code/Magento/ProductVideo/i18n/es_ES.csv b/app/code/Magento/ProductVideo/i18n/es_ES.csv
index 70473173969..ca24668bb8d 100644
--- a/app/code/Magento/ProductVideo/i18n/es_ES.csv
+++ b/app/code/Magento/ProductVideo/i18n/es_ES.csv
@@ -7,3 +7,4 @@
"Preview Image","Preview Image"
"Get Video Information","Get Video Information"
"Youtube or Vimeo supported","Youtube or Vimeo supported"
+"Delete image in all store views","Delete image in all store views"
diff --git a/app/code/Magento/ProductVideo/i18n/fr_FR.csv b/app/code/Magento/ProductVideo/i18n/fr_FR.csv
index 70473173969..ca24668bb8d 100644
--- a/app/code/Magento/ProductVideo/i18n/fr_FR.csv
+++ b/app/code/Magento/ProductVideo/i18n/fr_FR.csv
@@ -7,3 +7,4 @@
"Preview Image","Preview Image"
"Get Video Information","Get Video Information"
"Youtube or Vimeo supported","Youtube or Vimeo supported"
+"Delete image in all store views","Delete image in all store views"
diff --git a/app/code/Magento/ProductVideo/i18n/nl_NL.csv b/app/code/Magento/ProductVideo/i18n/nl_NL.csv
index 70473173969..5ad83865730 100644
--- a/app/code/Magento/ProductVideo/i18n/nl_NL.csv
+++ b/app/code/Magento/ProductVideo/i18n/nl_NL.csv
@@ -7,3 +7,4 @@
"Preview Image","Preview Image"
"Get Video Information","Get Video Information"
"Youtube or Vimeo supported","Youtube or Vimeo supported"
+"Delete image in all store views","Delete image in all store views"
\ No newline at end of file
diff --git a/app/code/Magento/ProductVideo/i18n/pt_BR.csv b/app/code/Magento/ProductVideo/i18n/pt_BR.csv
index 70473173969..5ad83865730 100644
--- a/app/code/Magento/ProductVideo/i18n/pt_BR.csv
+++ b/app/code/Magento/ProductVideo/i18n/pt_BR.csv
@@ -7,3 +7,4 @@
"Preview Image","Preview Image"
"Get Video Information","Get Video Information"
"Youtube or Vimeo supported","Youtube or Vimeo supported"
+"Delete image in all store views","Delete image in all store views"
\ No newline at end of file
diff --git a/app/code/Magento/ProductVideo/i18n/zh_Hans_CN.csv b/app/code/Magento/ProductVideo/i18n/zh_Hans_CN.csv
index 70473173969..5ad83865730 100644
--- a/app/code/Magento/ProductVideo/i18n/zh_Hans_CN.csv
+++ b/app/code/Magento/ProductVideo/i18n/zh_Hans_CN.csv
@@ -7,3 +7,4 @@
"Preview Image","Preview Image"
"Get Video Information","Get Video Information"
"Youtube or Vimeo supported","Youtube or Vimeo supported"
+"Delete image in all store views","Delete image in all store views"
\ No newline at end of file
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/layout/catalog_product_new.xml b/app/code/Magento/ProductVideo/view/adminhtml/layout/catalog_product_new.xml
index f5a22c50e6d..63bd5321ad3 100644
--- a/app/code/Magento/ProductVideo/view/adminhtml/layout/catalog_product_new.xml
+++ b/app/code/Magento/ProductVideo/view/adminhtml/layout/catalog_product_new.xml
@@ -6,6 +6,9 @@
*/
-->
+
+
+
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml b/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml
index 8b0f7d8ed98..6dff5321189 100755
--- a/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml
+++ b/app/code/Magento/ProductVideo/view/adminhtml/templates/helper/gallery.phtml
@@ -140,30 +140,37 @@ $elementToggleCode = $element->getToggleCode() ? $element->getToggleCode() : 'to
alt="<%- data.label %>"/>
-
+
= $block->escapeHtml(
@@ -329,4 +336,4 @@ $elementToggleCode = $element->getToggleCode() ? $element->getToggleCode() : 'to
+
\ No newline at end of file
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/css/gallery-delete-tooltip.css b/app/code/Magento/ProductVideo/view/adminhtml/web/css/gallery-delete-tooltip.css
new file mode 100644
index 00000000000..ad779c3f29b
--- /dev/null
+++ b/app/code/Magento/ProductVideo/view/adminhtml/web/css/gallery-delete-tooltip.css
@@ -0,0 +1,20 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+.gallery .tooltip .delete-tooltiptext {
+ visibility: hidden;
+ width: 112px;
+ background-color: #373330;
+ color: #F7F3EB;
+ text-align: center;
+ padding: 5px 0;
+ position: absolute;
+ z-index: 1;
+ left: 30px;
+ top: 91px;
+}
+
+.gallery .tooltip:hover .delete-tooltiptext {
+ visibility: visible;
+}
\ No newline at end of file
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js b/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js
index 287c88e8a79..e9b234c5f11 100644
--- a/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js
+++ b/app/code/Magento/ProductVideo/view/adminhtml/web/js/new-video-dialog.js
@@ -87,6 +87,9 @@ define([
* @private
*/
_doUpdate: function () {
+ var uploaderLinkUrl,
+ uploaderLink;
+
this.reset();
this.element.find(this.options.container).append(
'' +
- this.options.metaData.data.uploader +
- ''
- );
+ uploaderLinkUrl = 'https://youtube.com/channel/' + this.options.metaData.data.uploaderUrl;
} else if (this.options.videoProvider === 'vimeo') {
- this.element.find(this.options.metaData.DOM.uploader).html(
- '
' + this.options.metaData.data.uploader +
- '');
+ uploaderLinkUrl = this.options.metaData.data.uploaderUrl;
}
+ uploaderLink = document.createElement('a');
+ uploaderLink.setAttribute('href', uploaderLinkUrl);
+ uploaderLink.setAttribute('target', '_blank');
+ uploaderLink.innerText = this.options.metaData.data.uploader;
+ this.element.find(this.options.metaData.DOM.uploader)[0].appendChild(uploaderLink);
this.element.find('.' + this.options.videoClass).productVideoLoader();
},
diff --git a/app/code/Magento/Quote/Model/MaskedQuoteIdToQuoteId.php b/app/code/Magento/Quote/Model/MaskedQuoteIdToQuoteId.php
index f30d98342be..37a8fcd494f 100644
--- a/app/code/Magento/Quote/Model/MaskedQuoteIdToQuoteId.php
+++ b/app/code/Magento/Quote/Model/MaskedQuoteIdToQuoteId.php
@@ -10,6 +10,9 @@
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\ResourceModel\Quote\QuoteIdMask as QuoteIdMaskResource;
+/**
+ * MaskedQuoteId to QuoteId resolver
+ */
class MaskedQuoteIdToQuoteId implements MaskedQuoteIdToQuoteIdInterface
{
/**
diff --git a/app/code/Magento/Quote/Model/QuoteIdToMaskedQuoteId.php b/app/code/Magento/Quote/Model/QuoteIdToMaskedQuoteId.php
index 5ddadfc22f5..2e802f47cfe 100644
--- a/app/code/Magento/Quote/Model/QuoteIdToMaskedQuoteId.php
+++ b/app/code/Magento/Quote/Model/QuoteIdToMaskedQuoteId.php
@@ -8,29 +8,40 @@
namespace Magento\Quote\Model;
use Magento\Quote\Api\CartRepositoryInterface;
+use Magento\Quote\Model\ResourceModel\Quote\QuoteIdMask as QuoteIdMaskResource;
+/**
+ * QuoteId to MaskedQuoteId resolver
+ */
class QuoteIdToMaskedQuoteId implements QuoteIdToMaskedQuoteIdInterface
{
/**
* @var QuoteIdMaskFactory
*/
private $quoteIdMaskFactory;
-
/**
* @var CartRepositoryInterface
*/
private $cartRepository;
+ /**
+ * @var QuoteIdMaskResource
+ */
+ private $quoteIdMaskResource;
+
/**
* @param QuoteIdMaskFactory $quoteIdMaskFactory
* @param CartRepositoryInterface $cartRepository
+ * @param QuoteIdMaskResource $quoteIdMaskResource
*/
public function __construct(
QuoteIdMaskFactory $quoteIdMaskFactory,
- CartRepositoryInterface $cartRepository
+ CartRepositoryInterface $cartRepository,
+ QuoteIdMaskResource $quoteIdMaskResource
) {
$this->quoteIdMaskFactory = $quoteIdMaskFactory;
$this->cartRepository = $cartRepository;
+ $this->quoteIdMaskResource = $quoteIdMaskResource;
}
/**
@@ -42,8 +53,9 @@ public function execute(int $quoteId): string
$this->cartRepository->get($quoteId);
$quoteIdMask = $this->quoteIdMaskFactory->create();
- $quoteIdMask->setQuoteId($quoteId)->save();
+ $this->quoteIdMaskResource->load($quoteIdMask, $quoteId, 'quote_id');
+ $maskedId = $quoteIdMask->getMaskedId() ?? '';
- return $quoteIdMask->getMaskedId();
+ return $maskedId;
}
}
diff --git a/app/code/Magento/Quote/etc/db_schema.xml b/app/code/Magento/Quote/etc/db_schema.xml
index 3bd7122e65d..725825e976a 100644
--- a/app/code/Magento/Quote/etc/db_schema.xml
+++ b/app/code/Magento/Quote/etc/db_schema.xml
@@ -9,7 +9,7 @@
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
+ comment="Entity ID"/>
+ comment="Entity ID"/>
diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/AddProductsToCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/AddProductsToCart.php
new file mode 100644
index 00000000000..96259f22649
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/Cart/AddProductsToCart.php
@@ -0,0 +1,81 @@
+cartRepository = $cartRepository;
+ $this->addProductToCart = $addProductToCart;
+ }
+
+ /**
+ * Add products to cart
+ *
+ * @param Quote $cart
+ * @param array $cartItems
+ * @throws GraphQlInputException
+ */
+ public function execute(Quote $cart, array $cartItems): void
+ {
+ foreach ($cartItems as $cartItemData) {
+ $this->addProductToCart->execute($cart, $cartItemData);
+ }
+
+ if ($cart->getData('has_error')) {
+ throw new GraphQlInputException(
+ __('Shopping cart error: %message', ['message' => $this->getCartErrors($cart)])
+ );
+ }
+
+ $this->cartRepository->save($cart);
+ }
+
+ /**
+ * Collecting cart errors
+ *
+ * @param Quote $cart
+ * @return string
+ */
+ private function getCartErrors(Quote $cart): string
+ {
+ $errorMessages = [];
+
+ /** @var AbstractMessage $error */
+ foreach ($cart->getErrors() as $error) {
+ $errorMessages[] = $error->getText();
+ }
+
+ return implode(PHP_EOL, $errorMessages);
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php
new file mode 100644
index 00000000000..aa5b41daebd
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/Cart/AddSimpleProductToCart.php
@@ -0,0 +1,149 @@
+arrayManager = $arrayManager;
+ $this->dataObjectFactory = $dataObjectFactory;
+ $this->productRepository = $productRepository;
+ }
+
+ /**
+ * Add simple product to cart
+ *
+ * @param Quote $cart
+ * @param array $cartItemData
+ * @return void
+ * @throws GraphQlNoSuchEntityException
+ * @throws GraphQlInputException
+ */
+ public function execute(Quote $cart, array $cartItemData): void
+ {
+ $sku = $this->extractSku($cartItemData);
+ $qty = $this->extractQty($cartItemData);
+ $customizableOptions = $this->extractCustomizableOptions($cartItemData);
+
+ try {
+ $product = $this->productRepository->get($sku);
+ } catch (NoSuchEntityException $e) {
+ throw new GraphQlNoSuchEntityException(__('Could not find a product with SKU "%sku"', ['sku' => $sku]));
+ }
+
+ $result = $cart->addProduct($product, $this->createBuyRequest($qty, $customizableOptions));
+
+ if (is_string($result)) {
+ throw new GraphQlInputException(__($result));
+ }
+ }
+
+ /**
+ * Extract SKU from cart item data
+ *
+ * @param array $cartItemData
+ * @return string
+ * @throws GraphQlInputException
+ */
+ private function extractSku(array $cartItemData): string
+ {
+ $sku = $this->arrayManager->get('data/sku', $cartItemData);
+ if (!isset($sku)) {
+ throw new GraphQlInputException(__('Missing key "sku" in cart item data'));
+ }
+ return (string)$sku;
+ }
+
+ /**
+ * Extract Qty from cart item data
+ *
+ * @param array $cartItemData
+ * @return float
+ * @throws GraphQlInputException
+ */
+ private function extractQty(array $cartItemData): float
+ {
+ $qty = $this->arrayManager->get('data/qty', $cartItemData);
+ if (!isset($qty)) {
+ throw new GraphQlInputException(__('Missing key "qty" in cart item data'));
+ }
+ return (float)$qty;
+ }
+
+ /**
+ * Extract Customizable Options from cart item data
+ *
+ * @param array $cartItemData
+ * @return array
+ */
+ private function extractCustomizableOptions(array $cartItemData): array
+ {
+ $customizableOptions = $this->arrayManager->get('customizable_options', $cartItemData, []);
+
+ $customizableOptionsData = [];
+ foreach ($customizableOptions as $customizableOption) {
+ $customizableOptionsData[$customizableOption['id']] = $customizableOption['value'];
+ }
+ return $customizableOptionsData;
+ }
+
+ /**
+ * Format GraphQl input data to a shape that buy request has
+ *
+ * @param float $qty
+ * @param array $customOptions
+ * @return DataObject
+ */
+ private function createBuyRequest(float $qty, array $customOptions): DataObject
+ {
+ return $this->dataObjectFactory->create([
+ 'data' => [
+ 'qty' => $qty,
+ 'options' => $customOptions,
+ ],
+ ]);
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromCart.php
new file mode 100644
index 00000000000..faefa686606
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractDataFromCart.php
@@ -0,0 +1,47 @@
+getAllItems() as $cartItem) {
+ $productData = $cartItem->getProduct()->getData();
+ $productData['model'] = $cartItem->getProduct();
+
+ $items[] = [
+ 'id' => $cartItem->getItemId(),
+ 'qty' => $cartItem->getQty(),
+ 'product' => $productData,
+ 'model' => $cartItem,
+ ];
+ }
+
+ return [
+ 'items' => $items,
+ ];
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/GetCartForUser.php b/app/code/Magento/QuoteGraphQl/Model/Cart/GetCartForUser.php
new file mode 100644
index 00000000000..9c50d4b8557
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/Cart/GetCartForUser.php
@@ -0,0 +1,89 @@
+maskedQuoteIdToQuoteId = $maskedQuoteIdToQuoteId;
+ $this->cartRepository = $cartRepository;
+ }
+
+ /**
+ * Get cart for user
+ *
+ * @param string $cartHash
+ * @param int|null $userId
+ * @return Quote
+ * @throws GraphQlAuthenticationException
+ * @throws GraphQlNoSuchEntityException
+ */
+ public function execute(string $cartHash, ?int $userId): Quote
+ {
+ try {
+ $cartId = $this->maskedQuoteIdToQuoteId->execute($cartHash);
+ } catch (NoSuchEntityException $exception) {
+ throw new GraphQlNoSuchEntityException(
+ __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $cartHash])
+ );
+ }
+
+ try {
+ /** @var Quote $cart */
+ $cart = $this->cartRepository->get($cartId);
+ } catch (NoSuchEntityException $e) {
+ throw new GraphQlNoSuchEntityException(
+ __('Could not find a cart with ID "%masked_cart_id"', ['masked_cart_id' => $cartHash])
+ );
+ }
+
+ $customerId = (int)$cart->getCustomerId();
+
+ /* Guest cart, allow operations */
+ if (!$customerId) {
+ return $cart;
+ }
+
+ if ($customerId !== $userId) {
+ throw new GraphQlAuthenticationException(
+ __(
+ 'The current user cannot perform operations on cart "%masked_cart_id"',
+ ['masked_cart_id' => $cartHash]
+ )
+ );
+ }
+ return $cart;
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOption.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOption.php
new file mode 100644
index 00000000000..3199668060e
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOption.php
@@ -0,0 +1,66 @@
+customizableOptionValue = $customOptionValueDataProvider;
+ }
+
+ /**
+ * Retrieve custom option data
+ *
+ * @param QuoteItem $cartItem
+ * @param int $optionId
+ * @return array
+ * @throws LocalizedException
+ */
+ public function getData(QuoteItem $cartItem, int $optionId): array
+ {
+ $product = $cartItem->getProduct();
+ $option = $product->getOptionById($optionId);
+
+ if (!$option) {
+ return [];
+ }
+
+ $selectedOption = $cartItem->getOptionByCode('option_' . $option->getId());
+
+ $selectedOptionValueData = $this->customizableOptionValue->getData(
+ $cartItem,
+ $option,
+ $selectedOption
+ );
+
+ return [
+ 'id' => $option->getId(),
+ 'label' => $option->getTitle(),
+ 'type' => $option->getType(),
+ 'values' => $selectedOptionValueData,
+ 'sort_order' => $option->getSortOrder(),
+ 'is_required' => $option->getIsRequire(),
+ ];
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Composite.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Composite.php
new file mode 100644
index 00000000000..52978451253
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Composite.php
@@ -0,0 +1,68 @@
+objectManager = $objectManager;
+ $this->customizableOptionValues = $customizableOptionValues;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getData(
+ QuoteItem $cartItem,
+ Option $option,
+ SelectedOption $selectedOption
+ ): array {
+ $optionType = $option->getType();
+
+ if (!array_key_exists($optionType, $this->customizableOptionValues)) {
+ throw new GraphQlInputException(__('Option type "%1" is not supported', $optionType));
+ }
+ $customizableOptionValueClassName = $this->customizableOptionValues[$optionType];
+
+ $customizableOptionValue = $this->objectManager->get($customizableOptionValueClassName);
+ if (!$customizableOptionValue instanceof CustomizableOptionValueInterface) {
+ throw new LocalizedException(
+ __('%1 doesn\'t implement CustomizableOptionValueInterface', $customizableOptionValueClassName)
+ );
+ }
+ return $customizableOptionValue->getData($cartItem, $option, $selectedOption);
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Dropdown.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Dropdown.php
new file mode 100644
index 00000000000..74ed4034650
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Dropdown.php
@@ -0,0 +1,65 @@
+priceUnitLabel = $priceUnitLabel;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getData(
+ QuoteItem $cartItem,
+ Option $option,
+ SelectedOption $selectedOption
+ ): array {
+ /** @var SelectOptionType $optionTypeRenderer */
+ $optionTypeRenderer = $option->groupFactory($option->getType())
+ ->setOption($option)
+ ->setConfigurationItemOption($selectedOption);
+
+ $selectedValue = $selectedOption->getValue();
+ $optionValue = $option->getValueById($selectedValue);
+ $optionPriceType = (string)$optionValue->getPriceType();
+ $priceValueUnits = $this->priceUnitLabel->getData($optionPriceType);
+
+ $selectedOptionValueData = [
+ 'id' => $selectedOption->getId(),
+ 'label' => $optionTypeRenderer->getFormattedOptionValue($selectedValue),
+ 'value' => $selectedValue,
+ 'price' => [
+ 'type' => strtoupper($optionPriceType),
+ 'units' => $priceValueUnits,
+ 'value' => $optionValue->getPrice(),
+ ]
+ ];
+ return [$selectedOptionValueData];
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Multiple.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Multiple.php
new file mode 100644
index 00000000000..619e84568a5
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Multiple.php
@@ -0,0 +1,67 @@
+priceUnitLabel = $priceUnitLabel;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getData(
+ QuoteItem $cartItem,
+ Option $option,
+ SelectedOption $selectedOption
+ ): array {
+ $selectedOptionValueData = [];
+ $optionIds = explode(',', $selectedOption->getValue());
+
+ if (0 === count($optionIds)) {
+ return $selectedOptionValueData;
+ }
+
+ foreach ($optionIds as $optionId) {
+ $optionValue = $option->getValueById($optionId);
+ $priceValueUnits = $this->priceUnitLabel->getData($optionValue->getPriceType());
+
+ $selectedOptionValueData[] = [
+ 'id' => $selectedOption->getId(),
+ 'label' => $optionValue->getTitle(),
+ 'price' => [
+ 'type' => strtoupper($optionValue->getPriceType()),
+ 'units' => $priceValueUnits,
+ 'value' => $optionValue->getPrice(),
+ ],
+ ];
+ }
+
+ return $selectedOptionValueData;
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/PriceUnitLabel.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/PriceUnitLabel.php
new file mode 100644
index 00000000000..bee2e54ed5f
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/PriceUnitLabel.php
@@ -0,0 +1,63 @@
+storeManager = $storeManager;
+ }
+
+ /**
+ * Retrieve price value unit
+ *
+ * @param string $priceType
+ * @return string
+ */
+ public function getData(string $priceType): string
+ {
+ if (ProductPriceOptionsInterface::VALUE_PERCENT == $priceType) {
+ return '%';
+ }
+
+ return $this->getCurrencySymbol();
+ }
+
+ /**
+ * Get currency symbol
+ *
+ * @return string
+ * @throws NoSuchEntityException
+ */
+ private function getCurrencySymbol(): string
+ {
+ /** @var Store|StoreInterface $store */
+ $store = $this->storeManager->getStore();
+
+ return $store->getBaseCurrency()->getCurrencySymbol();
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Text.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Text.php
new file mode 100644
index 00000000000..4b29eb6a4a6
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValue/Text.php
@@ -0,0 +1,59 @@
+priceUnitLabel = $priceUnitLabel;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getData(
+ QuoteItem $cartItem,
+ Option $option,
+ SelectedOption $selectedOption
+ ): array {
+ /** @var TextOptionType $optionTypeRenderer */
+ $optionTypeRenderer = $option->groupFactory($option->getType());
+ $priceValueUnits = $this->priceUnitLabel->getData($option->getPriceType());
+
+ $selectedOptionValueData = [
+ 'id' => $selectedOption->getId(),
+ 'label' => '',
+ 'value' => $optionTypeRenderer->getFormattedOptionValue($selectedOption->getValue()),
+ 'price' => [
+ 'type' => strtoupper($option->getPriceType()),
+ 'units' => $priceValueUnits,
+ 'value' => $option->getPrice(),
+ ],
+ ];
+ return [$selectedOptionValueData];
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValueInterface.php b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValueInterface.php
new file mode 100644
index 00000000000..fce8b80f6d4
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/CartItem/DataProvider/CustomizableOptionValueInterface.php
@@ -0,0 +1,32 @@
+arrayManager = $arrayManager;
+ $this->getCartForUser = $getCartForUser;
+ $this->addProductsToCart = $addProductsToCart;
+ $this->extractDataFromCart = $extractDataFromCart;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
+ {
+ $cartHash = $this->arrayManager->get('input/cart_id', $args);
+ $cartItems = $this->arrayManager->get('input/cartItems', $args);
+
+ if (!isset($cartHash)) {
+ throw new GraphQlInputException(__('Missing key "cart_id" in cart data'));
+ }
+
+ if (!isset($cartItems) || !is_array($cartItems) || empty($cartItems)) {
+ throw new GraphQlInputException(__('Missing key "cartItems" in cart data'));
+ }
+
+ $currentUserId = $context->getUserId();
+ $cart = $this->getCartForUser->execute((string)$cartHash, $currentUserId);
+
+ $this->addProductsToCart->execute($cart, $cartItems);
+ $cartData = $this->extractDataFromCart->execute($cart);
+
+ return [
+ 'cart' => $cartData,
+ ];
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/ApplyCouponToCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/ApplyCouponToCart.php
new file mode 100644
index 00000000000..ec59416d493
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/ApplyCouponToCart.php
@@ -0,0 +1,88 @@
+getCartForUser = $getCartForUser;
+ $this->couponManagement = $couponManagement;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
+ {
+ if (!isset($args['input']['cart_id'])) {
+ throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
+ }
+ $maskedCartId = $args['input']['cart_id'];
+
+ if (!isset($args['input']['coupon_code'])) {
+ throw new GraphQlInputException(__('Required parameter "coupon_code" is missing'));
+ }
+ $couponCode = $args['input']['coupon_code'];
+
+ $currentUserId = $context->getUserId();
+ $cart = $this->getCartForUser->execute($maskedCartId, $currentUserId);
+ $cartId = $cart->getId();
+
+ /* Check current cart does not have coupon code applied */
+ $appliedCouponCode = $this->couponManagement->get($cartId);
+ if (!empty($appliedCouponCode)) {
+ throw new GraphQlInputException(
+ __('A coupon is already applied to the cart. Please remove it to apply another')
+ );
+ }
+
+ try {
+ $this->couponManagement->set($cartId, $couponCode);
+ } catch (NoSuchEntityException $exception) {
+ throw new GraphQlNoSuchEntityException(__($exception->getMessage()));
+ } catch (CouldNotSaveException $exception) {
+ throw new LocalizedException(__($exception->getMessage()));
+ }
+
+ $data['cart']['applied_coupon'] = [
+ 'code' => $couponCode,
+ ];
+ return $data;
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CartItemTypeResolver.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartItemTypeResolver.php
new file mode 100644
index 00000000000..962463860a5
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CartItemTypeResolver.php
@@ -0,0 +1,54 @@
+supportedTypes = $supportedTypes;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolveType(array $data) : string
+ {
+ if (!isset($data['product'])) {
+ throw new LocalizedException(__('Missing key "product" in cart data'));
+ }
+ $productData = $data['product'];
+
+ if (!isset($productData['type_id'])) {
+ throw new LocalizedException(__('Missing key "type_id" in product data'));
+ }
+ $productTypeId = $productData['type_id'];
+
+ if (!isset($this->supportedTypes[$productTypeId])) {
+ throw new LocalizedException(
+ __('Product "%product_type" type is not supported', ['product_type' => $productTypeId])
+ );
+ }
+ return $this->supportedTypes[$productTypeId];
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/Cart/CreateEmptyCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CreateEmptyCart.php
similarity index 70%
rename from app/code/Magento/QuoteGraphQl/Model/Resolver/Cart/CreateEmptyCart.php
rename to app/code/Magento/QuoteGraphQl/Model/Resolver/CreateEmptyCart.php
index fcf23dd9f68..06123abe615 100644
--- a/app/code/Magento/QuoteGraphQl/Model/Resolver/Cart/CreateEmptyCart.php
+++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CreateEmptyCart.php
@@ -5,15 +5,15 @@
*/
declare(strict_types=1);
-namespace Magento\QuoteGraphQl\Model\Resolver\Cart;
+namespace Magento\QuoteGraphQl\Model\Resolver;
-use Magento\Authorization\Model\UserContextInterface;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Quote\Api\CartManagementInterface;
use Magento\Quote\Api\GuestCartManagementInterface;
use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface;
+use Magento\Quote\Model\QuoteIdMaskFactory;
/**
* @inheritdoc
@@ -36,26 +36,26 @@ class CreateEmptyCart implements ResolverInterface
private $quoteIdToMaskedId;
/**
- * @var UserContextInterface
+ * @var QuoteIdMaskFactory
*/
- private $userContext;
+ private $quoteIdMaskFactory;
/**
* @param CartManagementInterface $cartManagement
* @param GuestCartManagementInterface $guestCartManagement
- * @param UserContextInterface $userContext
* @param QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedId
+ * @param QuoteIdMaskFactory $quoteIdMaskFactory
*/
public function __construct(
CartManagementInterface $cartManagement,
GuestCartManagementInterface $guestCartManagement,
- UserContextInterface $userContext,
- QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedId
+ QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedId,
+ QuoteIdMaskFactory $quoteIdMaskFactory
) {
$this->cartManagement = $cartManagement;
$this->guestCartManagement = $guestCartManagement;
- $this->userContext = $userContext;
$this->quoteIdToMaskedId = $quoteIdToMaskedId;
+ $this->quoteIdMaskFactory = $quoteIdMaskFactory;
}
/**
@@ -63,11 +63,17 @@ public function __construct(
*/
public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
{
- $customerId = $this->userContext->getUserId();
+ $customerId = $context->getUserId();
if (0 !== $customerId && null !== $customerId) {
$quoteId = $this->cartManagement->createEmptyCartForCustomer($customerId);
- $maskedQuoteId = $this->quoteIdToMaskedId->execute($quoteId);
+ $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$quoteId);
+
+ if (empty($maskedQuoteId)) {
+ $quoteIdMask = $this->quoteIdMaskFactory->create();
+ $quoteIdMask->setQuoteId($quoteId)->save();
+ $maskedQuoteId = $quoteIdMask->getMaskedId();
+ }
} else {
$maskedQuoteId = $this->guestCartManagement->createEmptyCart();
}
diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/CustomizableOptions.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/CustomizableOptions.php
new file mode 100644
index 00000000000..a681b2ca0d0
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/CustomizableOptions.php
@@ -0,0 +1,65 @@
+customizableOption = $customizableOption;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
+ {
+ if (!isset($value['model'])) {
+ throw new LocalizedException(__('"model" value should be specified'));
+ }
+
+ /** @var QuoteItem $cartItem */
+ $cartItem = $value['model'];
+ $quoteItemOption = $cartItem->getOptionByCode('option_ids');
+
+ if (null === $quoteItemOption) {
+ return [];
+ }
+
+ $customizableOptionsData = [];
+ $customizableOptionIds = explode(',', $quoteItemOption->getValue());
+
+ foreach ($customizableOptionIds as $customizableOptionId) {
+ $customizableOption = $this->customizableOption->getData(
+ $cartItem,
+ (int)$customizableOptionId
+ );
+ $customizableOptionsData[] = $customizableOption;
+ }
+ return $customizableOptionsData;
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveCouponFromCart.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveCouponFromCart.php
new file mode 100644
index 00000000000..c21d869ddac
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/RemoveCouponFromCart.php
@@ -0,0 +1,75 @@
+getCartForUser = $getCartForUser;
+ $this->couponManagement = $couponManagement;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
+ {
+ if (!isset($args['input']['cart_id'])) {
+ throw new GraphQlInputException(__('Required parameter "cart_id" is missing'));
+ }
+ $maskedCartId = $args['input']['cart_id'];
+
+ $currentUserId = $context->getUserId();
+ $cart = $this->getCartForUser->execute($maskedCartId, $currentUserId);
+ $cartId = $cart->getId();
+
+ try {
+ $this->couponManagement->remove($cartId);
+ } catch (NoSuchEntityException $exception) {
+ throw new GraphQlNoSuchEntityException(__($exception->getMessage()));
+ } catch (CouldNotDeleteException $exception) {
+ throw new LocalizedException(__($exception->getMessage()));
+ }
+
+ $data['cart']['applied_coupon'] = [
+ 'code' => '',
+ ];
+ return $data;
+ }
+}
diff --git a/app/code/Magento/QuoteGraphQl/composer.json b/app/code/Magento/QuoteGraphQl/composer.json
index 76ecfac373e..c9900dd5f31 100644
--- a/app/code/Magento/QuoteGraphQl/composer.json
+++ b/app/code/Magento/QuoteGraphQl/composer.json
@@ -5,12 +5,12 @@
"require": {
"php": "~7.1.3||~7.2.0",
"magento/framework": "*",
- "magento/module-authorization": "*",
- "magento/module-quote": "*"
+ "magento/module-quote": "*",
+ "magento/module-catalog": "*",
+ "magento/module-store": "*"
},
"suggest": {
- "magento/module-graph-ql": "*",
- "magento/module-catalog-graph-ql": "*"
+ "magento/module-graph-ql": "*"
},
"license": [
"OSL-3.0",
diff --git a/app/code/Magento/QuoteGraphQl/etc/di.xml b/app/code/Magento/QuoteGraphQl/etc/di.xml
new file mode 100644
index 00000000000..63ad9e193b9
--- /dev/null
+++ b/app/code/Magento/QuoteGraphQl/etc/di.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+ - SimpleCartItem
+
+
+
+
+
+
+ - Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Text
+ - Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Text
+ - Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Text
+ - Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Text
+ - Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Text
+ - Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Dropdown
+ - Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Dropdown
+ - Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Dropdown
+ - Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Multiple
+
+
+
+
diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls
index 46d1b97d0ae..f692aa57b21 100644
--- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls
+++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls
@@ -2,5 +2,95 @@
# See COPYING.txt for license details.
type Mutation {
- createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\Cart\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user")
+ createEmptyCart: String @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CreateEmptyCart") @doc(description:"Creates empty shopping cart for guest or logged in user")
+ applyCouponToCart(input: ApplyCouponToCartInput): ApplyCouponToCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ApplyCouponToCart")
+ removeCouponFromCart(input: RemoveCouponFromCartInput): RemoveCouponFromCartOutput @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\RemoveCouponFromCart")
+ addSimpleProductsToCart(input: AddSimpleProductsToCartInput): AddSimpleProductsToCartOutput @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AddSimpleProductsToCart")
+}
+
+input ApplyCouponToCartInput {
+ cart_id: String!
+ coupon_code: String!
+}
+
+type ApplyCouponToCartOutput {
+ cart: Cart!
+}
+
+type Cart {
+ items: [CartItemInterface]
+ applied_coupon: AppliedCoupon
+}
+
+type CartAddress {
+ applied_coupon: AppliedCoupon
+}
+
+type AppliedCoupon {
+ code: String!
+}
+
+input RemoveCouponFromCartInput {
+ cart_id: String!
+}
+
+type RemoveCouponFromCartOutput {
+ cart: Cart
+}
+
+input AddSimpleProductsToCartInput {
+ cart_id: String!
+ cartItems: [SimpleProductCartItemInput!]!
+}
+
+input SimpleProductCartItemInput {
+ data: CartItemInput!
+ customizable_options:[CustomizableOptionInput!]
+}
+
+input CustomizableOptionInput {
+ id: Int!
+ value: String!
+}
+
+type AddSimpleProductsToCartOutput {
+ cart: Cart!
+}
+
+type SimpleCartItem implements CartItemInterface @doc(description: "Simple Cart Item") {
+ customizable_options: [SelectedCustomizableOption] @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\CustomizableOptions")
+}
+
+input CartItemInput {
+ sku: String!
+ qty: Float!
+}
+
+interface CartItemInterface @typeResolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\CartItemTypeResolver") {
+ id: String!
+ qty: Float!
+ product: ProductInterface!
+}
+
+type SelectedCustomizableOption {
+ id: Int!
+ label: String!
+ type: String!
+ is_required: Int!
+ values: [SelectedCustomizableOptionValue!]!
+ sort_order: Int!
+}
+
+type SelectedCustomizableOptionValue {
+ id: Int!
+ label: String!
+ value: String!
+ price: CartItemSelectedOptionValuePrice!
+ sort_order: Int!
+}
+
+type CartItemSelectedOptionValuePrice {
+ value: Float!
+ units: String!
+ type: PriceTypeEnum!
}
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Sales/Tax/Grid.php b/app/code/Magento/Reports/Block/Adminhtml/Sales/Tax/Grid.php
index 79deb27423b..f65a2b964fb 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Sales/Tax/Grid.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Sales/Tax/Grid.php
@@ -53,7 +53,8 @@ public function __construct(
}
/**
- * {@inheritdoc}
+ * @inheritdoc
+ *
* @codeCoverageIgnore
*/
protected function _construct()
@@ -64,7 +65,7 @@ protected function _construct()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function getResourceCollectionName()
{
@@ -74,7 +75,7 @@ public function getResourceCollectionName()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
protected function _prepareColumns()
{
@@ -123,7 +124,6 @@ protected function _prepareColumns()
[
'header' => __('Orders'),
'index' => 'orders_count',
- 'total' => 'sum',
'type' => 'number',
'sortable' => false,
'header_css_class' => 'col-qty',
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/AbstractReport.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/AbstractReport.php
index 683ddcd9b66..2fbff13a5b6 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/AbstractReport.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/AbstractReport.php
@@ -20,6 +20,7 @@
*
* @api
* @since 100.0.2
+ * @SuppressWarnings(PHPMD.AllPurposeAction)
*/
abstract class AbstractReport extends \Magento\Backend\App\Action
{
@@ -149,15 +150,19 @@ protected function _showLastExecutionTime($flagCode, $refreshCode)
}
$refreshStatsLink = $this->getUrl('reports/report_statistics');
- $directRefreshLink = $this->getUrl('reports/report_statistics/refreshRecent', ['code' => $refreshCode]);
+ $directRefreshLink = $this->getUrl('reports/report_statistics/refreshRecent');
$this->messageManager->addNotice(
__(
'Last updated: %1. To refresh last day\'s statistics, ' .
- 'click here.',
+ 'click here.',
$updatedAt,
$refreshStatsLink,
- $directRefreshLink
+ str_replace(
+ '"',
+ '"',
+ json_encode(['action' => $directRefreshLink, 'data' => ['code' => $refreshCode]])
+ )
)
);
return $this;
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Accounts.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Accounts.php
index ae1c0401add..f8d0cbe9e69 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Accounts.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Accounts.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
-class Accounts extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Accounts extends \Magento\Reports\Controller\Adminhtml\Report\Customer implements HttpGetActionInterface
{
/**
* New accounts action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Orders.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Orders.php
index 56a594ac24e..be46fb6a94c 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Orders.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Orders.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
-class Orders extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Orders extends \Magento\Reports\Controller\Adminhtml\Report\Customer implements HttpGetActionInterface
{
/**
* Customers by number of orders action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Totals.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Totals.php
index 17928872eba..02f40e5be98 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Totals.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Totals.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
-class Totals extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Totals extends \Magento\Reports\Controller\Adminhtml\Report\Customer implements HttpGetActionInterface
{
/**
* Customers by orders total action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Downloads.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Downloads.php
index e8df3118caa..f2c03d0dc22 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Downloads.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Downloads.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Product;
-class Downloads extends \Magento\Reports\Controller\Adminhtml\Report\Product
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Downloads extends \Magento\Reports\Controller\Adminhtml\Report\Product implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Lowstock.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Lowstock.php
index b5e3602383f..266d6a85341 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Lowstock.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Lowstock.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Product;
-class Lowstock extends \Magento\Reports\Controller\Adminhtml\Report\Product
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Lowstock extends \Magento\Reports\Controller\Adminhtml\Report\Product implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Sold.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Sold.php
index 19b8258beaa..f01c46f4c14 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Sold.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Sold.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Product;
-class Sold extends \Magento\Reports\Controller\Adminhtml\Report\Product
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Sold extends \Magento\Reports\Controller\Adminhtml\Report\Product implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
index 07beec5a727..980540fb1fa 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Reports\Model\Flag;
-class Viewed extends \Magento\Reports\Controller\Adminhtml\Report\Product
+class Viewed extends \Magento\Reports\Controller\Adminhtml\Report\Product implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Customer.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Customer.php
index 50b1f79abd4..481522b86f0 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Customer.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Customer.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Review;
-class Customer extends \Magento\Reports\Controller\Adminhtml\Report\Review
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Customer extends \Magento\Reports\Controller\Adminhtml\Report\Review implements HttpGetActionInterface
{
/**
* Customer Reviews Report action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Product.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Product.php
index 3d0ebc5f568..911a313377c 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Product.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Product.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Review;
-class Product extends \Magento\Reports\Controller\Adminhtml\Report\Review
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Product extends \Magento\Reports\Controller\Adminhtml\Report\Review implements HttpGetActionInterface
{
/**
* Product reviews report action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Bestsellers.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Bestsellers.php
index 60f8cc87f2a..eff3796b6d4 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Bestsellers.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Bestsellers.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Reports\Model\Flag;
-class Bestsellers extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+class Bestsellers extends \Magento\Reports\Controller\Adminhtml\Report\Sales implements HttpGetActionInterface
{
/**
* Bestsellers report action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Coupons.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Coupons.php
index 2e324bceee3..d9e83cd77b9 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Coupons.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Coupons.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Reports\Model\Flag;
-class Coupons extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+class Coupons extends \Magento\Reports\Controller\Adminhtml\Report\Sales implements HttpGetActionInterface
{
/**
* Coupons report action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Invoiced.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Invoiced.php
index f533d597990..c26b0f931e6 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Invoiced.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Invoiced.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Reports\Model\Flag;
-class Invoiced extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+class Invoiced extends \Magento\Reports\Controller\Adminhtml\Report\Sales implements HttpGetActionInterface
{
/**
* Invoice report action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Refunded.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Refunded.php
index 85c5fdaed42..f88e9f64b97 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Refunded.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Refunded.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Reports\Model\Flag;
-class Refunded extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+class Refunded extends \Magento\Reports\Controller\Adminhtml\Report\Sales implements HttpGetActionInterface
{
/**
* Refunds report action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Sales.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Sales.php
index d6460864c5c..e3f383ab5a7 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Sales.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Sales.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Reports\Model\Flag;
-class Sales extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+class Sales extends \Magento\Reports\Controller\Adminhtml\Report\Sales implements HttpGetActionInterface
{
/**
* Sales report action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Tax.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Tax.php
index e8ae11088f5..2e6ba487f39 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Tax.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Tax.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Reports\Model\Flag;
-class Tax extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+class Tax extends \Magento\Reports\Controller\Adminhtml\Report\Sales implements HttpGetActionInterface
{
/**
* Tax report action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Abandoned.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Abandoned.php
index e03f2f65560..3f0567c05a9 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Abandoned.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Abandoned.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
-class Abandoned extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Abandoned extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart implements HttpGetActionInterface
{
/**
* Abandoned carts action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Product.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Product.php
index 65db66f2d2e..b41c901fe85 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Product.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Product.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
-class Product extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Product extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart implements HttpGetActionInterface
{
/**
* Products in carts action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/Index.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/Index.php
index d9f9de39657..61ec31337db 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/Index.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Statistics;
-class Index extends \Magento\Reports\Controller\Adminhtml\Report\Statistics
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\Reports\Controller\Adminhtml\Report\Statistics implements HttpGetActionInterface
{
/**
* Refresh statistics action
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
index 1f0f6e8e405..66123938243 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
@@ -6,7 +6,12 @@
*/
namespace Magento\Reports\Controller\Adminhtml\Report\Statistics;
-class RefreshRecent extends \Magento\Reports\Controller\Adminhtml\Report\Statistics
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
+
+/**
+ * Refresh recent stats.
+ */
+class RefreshRecent extends \Magento\Reports\Controller\Adminhtml\Report\Statistics implements HttpPostActionInterface
{
/**
* Refresh statistics for last 25 hours
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Edit.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Edit.php
index a39b22ec080..7d922f30cd9 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product/Edit.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Edit.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Review\Controller\Adminhtml\Product;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Review\Controller\Adminhtml\Product as ProductController;
use Magento\Framework\Controller\ResultFactory;
-class Edit extends ProductController
+class Edit extends ProductController implements HttpGetActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Page
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Index.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Index.php
index 0dce5b23883..94c80f89f8d 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product/Index.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Index.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Review\Controller\Adminhtml\Product;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Review\Controller\Adminhtml\Product as ProductController;
use Magento\Framework\Controller\ResultFactory;
-class Index extends ProductController
+class Index extends ProductController implements HttpGetActionInterface
{
/**
* @return \Magento\Framework\Controller\ResultInterface
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php b/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php
index c6e9cc81d58..bfd4b5e7470 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php
@@ -5,6 +5,7 @@
*/
namespace Magento\Review\Controller\Adminhtml\Product;
+use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Review\Controller\Adminhtml\Product as ProductController;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Registry;
@@ -14,7 +15,7 @@
use Magento\Framework\DataObject;
use Magento\Framework\Controller\ResultFactory;
-class JsonProductInfo extends ProductController
+class JsonProductInfo extends ProductController implements HttpGetActionInterface
{
/**
* @var \Magento\Catalog\Api\ProductRepositoryInterface
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php b/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php
index 5ac3a6a0572..2709b5ce64b 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Review\Controller\Adminhtml\Product;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Review\Controller\Adminhtml\Product as ProductController;
use Magento\Framework\Controller\ResultFactory;
-class NewAction extends ProductController
+class NewAction extends ProductController implements HttpGetActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Page
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Post.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Post.php
index 1f21a52077b..b62fcc7326e 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product/Post.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Post.php
@@ -5,12 +5,13 @@
*/
namespace Magento\Review\Controller\Adminhtml\Product;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Review\Controller\Adminhtml\Product as ProductController;
use Magento\Framework\Controller\ResultFactory;
use Magento\Store\Model\Store;
use Magento\Framework\Exception\LocalizedException;
-class Post extends ProductController
+class Post extends ProductController implements HttpPostActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Redirect
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/ProductGrid.php b/app/code/Magento/Review/Controller/Adminhtml/Product/ProductGrid.php
index f1b25c3613d..e4057be14af 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product/ProductGrid.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/ProductGrid.php
@@ -5,6 +5,8 @@
*/
namespace Magento\Review\Controller\Adminhtml\Product;
+use Magento\Framework\App\Action\HttpGetActionInterface;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Review\Controller\Adminhtml\Product as ProductController;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Registry;
@@ -13,7 +15,7 @@
use Magento\Framework\View\LayoutFactory;
use Magento\Framework\Controller\ResultFactory;
-class ProductGrid extends ProductController
+class ProductGrid extends ProductController implements HttpPostActionInterface, HttpGetActionInterface
{
/**
* @var \Magento\Framework\View\LayoutFactory
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/RatingItems.php b/app/code/Magento/Review/Controller/Adminhtml/Product/RatingItems.php
index 5b0ab217e71..1da8e4abbd6 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product/RatingItems.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/RatingItems.php
@@ -5,6 +5,8 @@
*/
namespace Magento\Review\Controller\Adminhtml\Product;
+use Magento\Framework\App\Action\HttpGetActionInterface;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Review\Controller\Adminhtml\Product as ProductController;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Registry;
@@ -13,7 +15,7 @@
use Magento\Framework\View\LayoutFactory;
use Magento\Framework\Controller\ResultFactory;
-class RatingItems extends ProductController
+class RatingItems extends ProductController implements HttpPostActionInterface, HttpGetActionInterface
{
/**
* @var \Magento\Framework\View\LayoutFactory
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php
index 7159b1825dc..35187e46933 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php
@@ -5,11 +5,12 @@
*/
namespace Magento\Review\Controller\Adminhtml\Product;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Review\Controller\Adminhtml\Product as ProductController;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Exception\LocalizedException;
-class Save extends ProductController
+class Save extends ProductController implements HttpPostActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Redirect
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating/Delete.php b/app/code/Magento/Review/Controller/Adminhtml/Rating/Delete.php
index 5535c3de26e..b25db6e498f 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Rating/Delete.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating/Delete.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Review\Controller\Adminhtml\Rating;
+use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Review\Controller\Adminhtml\Rating as RatingController;
use Magento\Framework\Controller\ResultFactory;
-class Delete extends RatingController
+class Delete extends RatingController implements HttpPostActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Redirect
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating/Edit.php b/app/code/Magento/Review/Controller/Adminhtml/Rating/Edit.php
index 1b65966b770..90dac026cfd 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Rating/Edit.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating/Edit.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Review\Controller\Adminhtml\Rating;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Review\Controller\Adminhtml\Rating as RatingController;
use Magento\Framework\Controller\ResultFactory;
-class Edit extends RatingController
+class Edit extends RatingController implements HttpGetActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Page
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating/Index.php b/app/code/Magento/Review/Controller/Adminhtml/Rating/Index.php
index b719a299505..ff9ab4d50ea 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Rating/Index.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating/Index.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Review\Controller\Adminhtml\Rating;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Review\Controller\Adminhtml\Rating as RatingController;
use Magento\Framework\Controller\ResultFactory;
-class Index extends RatingController
+class Index extends RatingController implements HttpGetActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Page
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating/NewAction.php b/app/code/Magento/Review/Controller/Adminhtml/Rating/NewAction.php
index 18ff73ad31c..92d20aeec3e 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Rating/NewAction.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating/NewAction.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Review\Controller\Adminhtml\Rating;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Review\Controller\Adminhtml\Rating as RatingController;
use Magento\Framework\Controller\ResultFactory;
-class NewAction extends RatingController
+class NewAction extends RatingController implements HttpGetActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Forward
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating/Save.php b/app/code/Magento/Review/Controller/Adminhtml/Rating/Save.php
index 62cca9c824e..5dd464f7eb6 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Rating/Save.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating/Save.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Review\Controller\Adminhtml\Rating;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Review\Controller\Adminhtml\Rating as RatingController;
use Magento\Framework\Controller\ResultFactory;
-class Save extends RatingController
+class Save extends RatingController implements HttpPostActionInterface
{
/**
* Save rating
diff --git a/app/code/Magento/Review/Controller/Product/ListAjax.php b/app/code/Magento/Review/Controller/Product/ListAjax.php
index a309b5f0626..d923814c7dc 100644
--- a/app/code/Magento/Review/Controller/Product/ListAjax.php
+++ b/app/code/Magento/Review/Controller/Product/ListAjax.php
@@ -11,8 +11,9 @@
use Magento\Framework\View\Result\Layout;
use Magento\Review\Controller\Product as ProductController;
use Magento\Framework\Controller\ResultFactory;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
-class ListAjax extends ProductController
+class ListAjax extends ProductController implements HttpGetActionInterface
{
/**
* Show list of product's reviews
diff --git a/app/code/Magento/Review/Controller/Product/Post.php b/app/code/Magento/Review/Controller/Product/Post.php
index be18f8fe25b..32838eb6acb 100644
--- a/app/code/Magento/Review/Controller/Product/Post.php
+++ b/app/code/Magento/Review/Controller/Product/Post.php
@@ -5,11 +5,12 @@
*/
namespace Magento\Review\Controller\Product;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Review\Controller\Product as ProductController;
use Magento\Framework\Controller\ResultFactory;
use Magento\Review\Model\Review;
-class Post extends ProductController
+class Post extends ProductController implements HttpPostActionInterface
{
/**
* Submit new review action
diff --git a/app/code/Magento/Review/etc/db_schema.xml b/app/code/Magento/Review/etc/db_schema.xml
index 1a2ff588180..2ae43ea608e 100644
--- a/app/code/Magento/Review/etc/db_schema.xml
+++ b/app/code/Magento/Review/etc/db_schema.xml
@@ -95,7 +95,7 @@
+ default="0" comment="Store ID"/>
@@ -108,9 +108,9 @@
+ comment="Review ID"/>
+ comment="Store ID"/>
@@ -125,7 +125,7 @@
+ comment="Entity ID"/>
@@ -136,9 +136,9 @@
+ comment="Rating ID"/>
+ default="0" comment="Entity ID"/>
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/History.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/History.php
index 1912655a929..10b80b6f4e5 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/History.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/History.php
@@ -88,7 +88,8 @@ public function getStatuses()
*/
public function canSendCommentEmail()
{
- return $this->_salesData->canSendOrderCommentEmail($this->getOrder()->getStore()->getId());
+ return $this->_salesData->canSendOrderCommentEmail($this->getOrder()->getStore()->getId())
+ && $this->_authorization->isAllowed('Magento_Sales::email');
}
/**
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php
index 64b53d10d4a..0972d743142 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php
@@ -61,6 +61,7 @@ public function getOrder()
/**
* Compose and get order full history.
+ *
* Consists of the status history comments as well as of invoices, shipments and creditmemos creations
*
* @TODO This method requires refactoring. Need to create separate model for comment history handling
@@ -218,7 +219,7 @@ protected function _prepareHistoryItem($label, $notified, $created, $comment = '
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function getTabLabel()
{
@@ -226,7 +227,7 @@ public function getTabLabel()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function getTabTitle()
{
@@ -264,7 +265,7 @@ public function getTabUrl()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function canShowTab()
{
@@ -272,7 +273,7 @@ public function canShowTab()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function isHidden()
{
@@ -303,11 +304,7 @@ public static function sortHistoryByTimestamp($a, $b)
$createdAtA = $a['created_at'];
$createdAtB = $b['created_at'];
- /** @var $createdAtA \DateTime */
- if ($createdAtA->getTimestamp() == $createdAtB->getTimestamp()) {
- return 0;
- }
- return $createdAtA->getTimestamp() < $createdAtB->getTimestamp() ? -1 : 1;
+ return $createdAtA->getTimestamp() <=> $createdAtB->getTimestamp();
}
/**
diff --git a/app/code/Magento/Sales/Block/Status/Grid/Column/Unassign.php b/app/code/Magento/Sales/Block/Status/Grid/Column/Unassign.php
index b413951d9d4..f989deb0ae7 100644
--- a/app/code/Magento/Sales/Block/Status/Grid/Column/Unassign.php
+++ b/app/code/Magento/Sales/Block/Status/Grid/Column/Unassign.php
@@ -5,12 +5,35 @@
*/
namespace Magento\Sales\Block\Status\Grid\Column;
+use Magento\Framework\App\ObjectManager;
+use \Magento\Backend\Block\Template\Context;
+use Magento\Framework\Serialize\Serializer\Json;
+
/**
* @api
* @since 100.0.2
*/
class Unassign extends \Magento\Backend\Block\Widget\Grid\Column
{
+ /**
+ * @var Json
+ */
+ private $json;
+
+ /**
+ * @inheritDoc
+ *
+ * @param Json|null $json
+ */
+ public function __construct(
+ Context $context,
+ array $data = [],
+ ?Json $json = null
+ ) {
+ parent::__construct($context, $data);
+ $this->json = $json ?? ObjectManager::getInstance()->get(Json::class);
+ }
+
/**
* Add decorated action to column
*
@@ -36,9 +59,16 @@ public function decorateAction($value, $row, $column, $isExport)
$cell = '';
$state = $row->getState();
if (!empty($state)) {
- $url = $this->getUrl('*/*/unassign', ['status' => $row->getStatus(), 'state' => $row->getState()]);
+ $url = $this->getUrl('*/*/unassign');
$label = __('Unassign');
- $cell = '' . $label . '';
+ $cell = '' . $label . '';
}
return $cell;
}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Index.php
index b29c1ea3700..165c9e894de 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Index.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Index.php
@@ -5,7 +5,10 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Creditmemo;
-class Index extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\Index
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+use Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\Index as AbstractIndex;
+
+class Index extends AbstractIndex implements HttpGetActionInterface
{
/**
* Index page
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Index.php
index 429a388d939..bc53f752801 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Index.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Index.php
@@ -6,6 +6,8 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Invoice;
-class Index extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\Index
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\Index implements HttpGetActionInterface
{
}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/View.php
index 62add99ab59..3b521999432 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/View.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/View.php
@@ -6,6 +6,8 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Invoice;
-class View extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class View extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View implements HttpGetActionInterface
{
}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
index 7e41c7417b3..f96d221a7d3 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order;
-class Cancel extends \Magento\Sales\Controller\Adminhtml\Order
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
+
+class Cancel extends \Magento\Sales\Controller\Adminhtml\Order implements HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/CommentsHistory.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/CommentsHistory.php
index 8496c4f28d8..4acef74b810 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/CommentsHistory.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/CommentsHistory.php
@@ -6,16 +6,20 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order;
+use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Backend\App\Action;
+use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Sales\Api\OrderManagementInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Psr\Log\LoggerInterface;
+use Magento\Sales\Controller\Adminhtml\Order as OrderAction;
/**
- * Class CommentsHistory
+ * Comments History tab, needs to be accessible by POST becuase of tabs mechanism.
+ *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class CommentsHistory extends \Magento\Sales\Controller\Adminhtml\Order
+class CommentsHistory extends OrderAction implements HttpGetActionInterface, HttpPostActionInterface
{
/**
* @var \Magento\Framework\View\LayoutFactory
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Index.php
index ce3a36729de..035dc787789 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Index.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Index.php
@@ -5,7 +5,9 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Create;
-class Index extends \Magento\Sales\Controller\Adminhtml\Order\Create
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Order\Create implements HttpGetActionInterface
{
/**
* Index page
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php
index bc4eb3cfba4..1e13e282cae 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php
@@ -5,12 +5,15 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+use Magento\Framework\App\Action\HttpGetActionInterface;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Backend\App\Action;
use Magento\Backend\Model\View\Result\ForwardFactory;
use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\Controller\Result\RawFactory;
+use Magento\Sales\Controller\Adminhtml\Order\Create as CreateAction;
-class LoadBlock extends \Magento\Sales\Controller\Adminhtml\Order\Create
+class LoadBlock extends CreateAction implements HttpPostActionInterface, HttpGetActionInterface
{
/**
* @var RawFactory
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Save.php
index 929e23075e0..4348984d040 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Save.php
@@ -6,9 +6,10 @@
namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\Exception\PaymentException;
-class Save extends \Magento\Sales\Controller\Adminhtml\Order\Create
+class Save extends \Magento\Sales\Controller\Adminhtml\Order\Create implements HttpPostActionInterface
{
/**
* Saving quote and create order
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ShowUpdateResult.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ShowUpdateResult.php
index 01119c3aa88..24aedf56ec5 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ShowUpdateResult.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ShowUpdateResult.php
@@ -5,12 +5,13 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Backend\App\Action;
use Magento\Backend\Model\View\Result\ForwardFactory;
use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\Controller\Result\RawFactory;
-class ShowUpdateResult extends \Magento\Sales\Controller\Adminhtml\Order\Create
+class ShowUpdateResult extends \Magento\Sales\Controller\Adminhtml\Order\Create implements HttpGetActionInterface
{
/**
* @var RawFactory
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Start.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Start.php
index ee88b3361cc..bc75bc4a578 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Start.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Start.php
@@ -5,9 +5,10 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Backend\App\Action;
-class Start extends \Magento\Sales\Controller\Adminhtml\Order\Create
+class Start extends \Magento\Sales\Controller\Adminhtml\Order\Create implements HttpGetActionInterface
{
/**
* Start order create action
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/NewAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/NewAction.php
index 03910f2eccc..3ac3abda82c 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/NewAction.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/NewAction.php
@@ -5,9 +5,10 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Backend\App\Action;
-class NewAction extends \Magento\Backend\App\Action
+class NewAction extends \Magento\Backend\App\Action implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
index 2a2445d2b2a..91ae3b7d4e0 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
@@ -5,11 +5,12 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Backend\App\Action;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Email\Sender\CreditmemoSender;
-class Save extends \Magento\Backend\App\Action
+class Save extends \Magento\Backend\App\Action implements HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Start.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Start.php
index 10ba7e425b6..3dc4aa6dcd5 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Start.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Start.php
@@ -5,7 +5,9 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
-class Start extends \Magento\Backend\App\Action
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Start extends \Magento\Backend\App\Action implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/UpdateQty.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/UpdateQty.php
index bfd95666e7c..d49fa8b8dc6 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/UpdateQty.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/UpdateQty.php
@@ -5,9 +5,10 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Backend\App\Action;
-class UpdateQty extends \Magento\Backend\App\Action
+class UpdateQty extends \Magento\Backend\App\Action implements HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Index.php
index 13a86befec0..d5dc1171923 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Index.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Index.php
@@ -5,7 +5,9 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order;
-class Index extends \Magento\Sales\Controller\Adminhtml\Order
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Order implements HttpGetActionInterface
{
/**
* Orders grid
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/NewAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/NewAction.php
index 2d7826807a6..3295b244f32 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/NewAction.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/NewAction.php
@@ -7,12 +7,13 @@
namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Backend\App\Action;
use Magento\Framework\Registry;
use Magento\Framework\View\Result\PageFactory;
use Magento\Sales\Model\Service\InvoiceService;
-class NewAction extends \Magento\Backend\App\Action
+class NewAction extends \Magento\Backend\App\Action implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
index 71338c818c4..ab74a64b6fc 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
@@ -7,6 +7,7 @@
namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Backend\App\Action;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Registry;
@@ -19,7 +20,7 @@
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class Save extends \Magento\Backend\App\Action
+class Save extends \Magento\Backend\App\Action implements HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Start.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Start.php
index ca97ee3b334..4648656a325 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Start.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Start.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
-class Start extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Start extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View implements HttpGetActionInterface
{
/**
* Start create invoice action
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/UpdateQty.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/UpdateQty.php
index 78fb4aff3f2..c94afa3cc80 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/UpdateQty.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/UpdateQty.php
@@ -7,20 +7,21 @@
namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\Exception\LocalizedException;
-use Magento\Backend\App\Action;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\Controller\Result\RawFactory;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Registry;
use Magento\Sales\Model\Service\InvoiceService;
+use Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View as AbstractView;
/**
* Class UpdateQty
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class UpdateQty extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View
+class UpdateQty extends AbstractView implements HttpPostActionInterface
{
/**
* @var JsonFactory
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php
index 78a413d5636..da700aae2f7 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php
@@ -6,11 +6,12 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Framework\View\Result\PageFactory;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Registry;
-class View extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View
+class View extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View implements HttpGetActionInterface
{
/**
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassCancel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassCancel.php
index 32cf6dbfc7c..deb20a989a2 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassCancel.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassCancel.php
@@ -5,13 +5,14 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory;
use Magento\Sales\Api\OrderManagementInterface;
-class MassCancel extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction
+class MassCancel extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction implements HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Assign.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Assign.php
index 982ee53cb0f..211ded865b4 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Assign.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Assign.php
@@ -6,11 +6,12 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Status;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Framework\Registry;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
-class Assign extends \Magento\Sales\Controller\Adminhtml\Order\Status
+class Assign extends \Magento\Sales\Controller\Adminhtml\Order\Status implements HttpGetActionInterface
{
/**
* @var PageFactory
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/AssignPost.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/AssignPost.php
index 3b98d206d5f..28a8e1cb02a 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/AssignPost.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/AssignPost.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Status;
-class AssignPost extends \Magento\Sales\Controller\Adminhtml\Order\Status
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
+
+class AssignPost extends \Magento\Sales\Controller\Adminhtml\Order\Status implements HttpPostActionInterface
{
/**
* Save status assignment to state
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Index.php
index 110402ee270..3755dca9da9 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Index.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Index.php
@@ -6,11 +6,12 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Status;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Framework\Registry;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
-class Index extends \Magento\Sales\Controller\Adminhtml\Order\Status
+class Index extends \Magento\Sales\Controller\Adminhtml\Order\Status implements HttpGetActionInterface
{
/**
* @var PageFactory
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Save.php
index bd0ad771815..4645588a752 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Save.php
@@ -6,25 +6,32 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Status;
-class Save extends \Magento\Sales\Controller\Adminhtml\Order\Status
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
+use Magento\Framework\Filter\FilterManager;
+use Magento\Sales\Model\Order\Status;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Controller\Result\Redirect;
+use Magento\Sales\Controller\Adminhtml\Order\Status as StatusAction;
+
+class Save extends StatusAction implements HttpPostActionInterface
{
/**
* Save status form processing
*
- * @return \Magento\Backend\Model\View\Result\Redirect
+ * @return Redirect
*/
public function execute()
{
$data = $this->getRequest()->getPostValue();
$isNew = $this->getRequest()->getParam('is_new');
- /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+ /** @var Redirect $resultRedirect */
$resultRedirect = $this->resultRedirectFactory->create();
if ($data) {
$statusCode = $this->getRequest()->getParam('status');
//filter tags in labels/status
- /** @var $filterManager \Magento\Framework\Filter\FilterManager */
- $filterManager = $this->_objectManager->get(\Magento\Framework\Filter\FilterManager::class);
+ /** @var $filterManager FilterManager */
+ $filterManager = $this->_objectManager->get(FilterManager::class);
if ($isNew) {
$statusCode = $data['status'] = $filterManager->stripTags($data['status']);
}
@@ -37,7 +44,7 @@ public function execute()
$label = $filterManager->stripTags($label);
}
- $status = $this->_objectManager->create(\Magento\Sales\Model\Order\Status::class)->load($statusCode);
+ $status = $this->_objectManager->create(Status::class)->load($statusCode);
// check if status exist
if ($isNew && $status->getStatus()) {
$this->messageManager
@@ -52,7 +59,7 @@ public function execute()
$status->save();
$this->messageManager->addSuccessMessage(__('You saved the order status.'));
return $resultRedirect->setPath('sales/*/');
- } catch (\Magento\Framework\Exception\LocalizedException $e) {
+ } catch (LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
$this->messageManager->addExceptionMessage(
@@ -67,11 +74,11 @@ public function execute()
}
/**
- * @param \Magento\Backend\Model\View\Result\Redirect $resultRedirect
+ * @param Redirect $resultRedirect
* @param bool $isNew
- * @return \Magento\Backend\Model\View\Result\Redirect
+ * @return Redirect
*/
- private function getRedirect(\Magento\Backend\Model\View\Result\Redirect $resultRedirect, $isNew)
+ private function getRedirect(Redirect $resultRedirect, $isNew)
{
if ($isNew) {
return $resultRedirect->setPath('sales/*/new');
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Unassign.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Unassign.php
index 2723d483dd3..16bb275a88e 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Unassign.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Unassign.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Order\Status;
-class Unassign extends \Magento\Sales\Controller\Adminhtml\Order\Status
+use Magento\Framework\App\Action\HttpPostActionInterface;
+
+class Unassign extends \Magento\Sales\Controller\Adminhtml\Order\Status implements HttpPostActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Redirect
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/Index.php
index c7f560c52fb..59d8a68a744 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/Index.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/Index.php
@@ -6,6 +6,9 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Shipment;
-class Index extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment\Index
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+use Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment\Index as AbstractIndex;
+
+class Index extends AbstractIndex implements HttpGetActionInterface
{
}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Index.php
index 750781e9919..a7327050064 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Index.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Index.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Sales\Controller\Adminhtml\Transactions;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Backend\Model\View\Result\Page;
-class Index extends \Magento\Sales\Controller\Adminhtml\Transactions
+class Index extends \Magento\Sales\Controller\Adminhtml\Transactions implements HttpGetActionInterface
{
/**
* @return Page
diff --git a/app/code/Magento/Sales/Controller/Order/Creditmemo.php b/app/code/Magento/Sales/Controller/Order/Creditmemo.php
index 2a7fd3e9849..74aae3e1f84 100644
--- a/app/code/Magento/Sales/Controller/Order/Creditmemo.php
+++ b/app/code/Magento/Sales/Controller/Order/Creditmemo.php
@@ -6,8 +6,10 @@
*/
namespace Magento\Sales\Controller\Order;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Sales\Controller\OrderInterface;
+use Magento\Sales\Controller\AbstractController\Creditmemo as AbstractCreditmemo;
-class Creditmemo extends \Magento\Sales\Controller\AbstractController\Creditmemo implements OrderInterface
+class Creditmemo extends AbstractCreditmemo implements OrderInterface, HttpGetActionInterface
{
}
diff --git a/app/code/Magento/Sales/Controller/Order/History.php b/app/code/Magento/Sales/Controller/Order/History.php
index 23e8208d8b1..37de1598458 100644
--- a/app/code/Magento/Sales/Controller/Order/History.php
+++ b/app/code/Magento/Sales/Controller/Order/History.php
@@ -6,11 +6,12 @@
*/
namespace Magento\Sales\Controller\Order;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Sales\Controller\OrderInterface;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
-class History extends \Magento\Framework\App\Action\Action implements OrderInterface
+class History extends \Magento\Framework\App\Action\Action implements OrderInterface, HttpGetActionInterface
{
/**
* @var PageFactory
diff --git a/app/code/Magento/Sales/Controller/Order/View.php b/app/code/Magento/Sales/Controller/Order/View.php
index d68b9481c86..21a5706a444 100644
--- a/app/code/Magento/Sales/Controller/Order/View.php
+++ b/app/code/Magento/Sales/Controller/Order/View.php
@@ -6,8 +6,9 @@
*/
namespace Magento\Sales\Controller\Order;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Sales\Controller\OrderInterface;
-class View extends \Magento\Sales\Controller\AbstractController\View implements OrderInterface
+class View extends \Magento\Sales\Controller\AbstractController\View implements OrderInterface, HttpGetActionInterface
{
}
diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php
index 7372d9715c7..9f30342ed33 100644
--- a/app/code/Magento/Sales/Model/Order.php
+++ b/app/code/Magento/Sales/Model/Order.php
@@ -16,7 +16,7 @@
use Magento\Sales\Model\ResourceModel\Order\Address\Collection;
use Magento\Sales\Model\ResourceModel\Order\Creditmemo\Collection as CreditmemoCollection;
use Magento\Sales\Model\ResourceModel\Order\Invoice\Collection as InvoiceCollection;
-use Magento\Sales\Model\ResourceModel\Order\Item\Collection as ImportCollection;
+use Magento\Sales\Model\ResourceModel\Order\Item\Collection as ItemCollection;
use Magento\Sales\Model\ResourceModel\Order\Payment\Collection as PaymentCollection;
use Magento\Sales\Model\ResourceModel\Order\Shipment\Collection as ShipmentCollection;
use Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection as TrackCollection;
@@ -564,6 +564,7 @@ public function canCancel()
/**
* Getter whether the payment can be voided
+ *
* @return bool
*/
public function canVoidPayment()
@@ -880,7 +881,7 @@ protected function _placePayment()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function getPayment()
{
@@ -1008,6 +1009,7 @@ public function addStatusToHistory($status, $comment = '', $isCustomerNotified =
/**
* Add a comment to order
+ *
* Different or default status may be specified
*
* @param string $comment
@@ -1023,6 +1025,7 @@ public function addStatusHistoryComment($comment, $status = false)
/**
* Add a comment to order status history
+ *
* Different or default status may be specified
*
* @param string $comment
@@ -1088,6 +1091,8 @@ public function place()
}
/**
+ * Hold order
+ *
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
@@ -1233,6 +1238,8 @@ public function getShippingMethod($asObject = false)
/*********************** ADDRESSES ***************************/
/**
+ * Returns address collection instance
+ *
* @return Collection
*/
public function getAddressesCollection()
@@ -1247,6 +1254,8 @@ public function getAddressesCollection()
}
/**
+ * Returns address by id
+ *
* @param mixed $addressId
* @return false
*/
@@ -1261,6 +1270,8 @@ public function getAddressById($addressId)
}
/**
+ * Add address to order
+ *
* @param \Magento\Sales\Model\Order\Address $address
* @return $this
*/
@@ -1275,9 +1286,11 @@ public function addAddress(\Magento\Sales\Model\Order\Address $address)
}
/**
+ * Returns items collection
+ *
* @param array $filterByTypes
* @param bool $nonChildrenOnly
- * @return ImportCollection
+ * @return ItemCollection
*/
public function getItemsCollection($filterByTypes = [], $nonChildrenOnly = false)
{
@@ -1302,7 +1315,7 @@ public function getItemsCollection($filterByTypes = [], $nonChildrenOnly = false
* Get random items collection without related children
*
* @param int $limit
- * @return ImportCollection
+ * @return ItemCollection
*/
public function getParentItemsRandomCollection($limit = 1)
{
@@ -1314,7 +1327,7 @@ public function getParentItemsRandomCollection($limit = 1)
*
* @param int $limit
* @param bool $nonChildrenOnly
- * @return ImportCollection
+ * @return ItemCollection
*/
protected function _getItemsRandomCollection($limit, $nonChildrenOnly = false)
{
@@ -1347,6 +1360,8 @@ protected function _getItemsRandomCollection($limit, $nonChildrenOnly = false)
}
/**
+ * Returns all order items
+ *
* @return \Magento\Sales\Model\Order\Item[]
*/
public function getAllItems()
@@ -1361,6 +1376,8 @@ public function getAllItems()
}
/**
+ * Returns all visible items
+ *
* @return array
*/
public function getAllVisibleItems()
@@ -1392,6 +1409,8 @@ public function getItemById($itemId)
}
/**
+ * Returns Item By QuoteItem Id
+ *
* @param mixed $quoteItemId
* @return \Magento\Framework\DataObject|null
*/
@@ -1406,6 +1425,8 @@ public function getItemByQuoteItemId($quoteItemId)
}
/**
+ * Add item to order
+ *
* @param \Magento\Sales\Model\Order\Item $item
* @return $this
*/
@@ -1421,6 +1442,8 @@ public function addItem(\Magento\Sales\Model\Order\Item $item)
/*********************** PAYMENTS ***************************/
/**
+ * Returns payment collection
+ *
* @return PaymentCollection
*/
public function getPaymentsCollection()
@@ -1435,6 +1458,8 @@ public function getPaymentsCollection()
}
/**
+ * Returns all payments
+ *
* @return array
*/
public function getAllPayments()
@@ -1449,6 +1474,8 @@ public function getAllPayments()
}
/**
+ * Returns payment by id
+ *
* @param mixed $paymentId
* @return Payment|false
*/
@@ -1463,7 +1490,7 @@ public function getPaymentById($paymentId)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setPayment(\Magento\Sales\Api\Data\OrderPaymentInterface $payment = null)
{
@@ -1530,6 +1557,8 @@ public function getVisibleStatusHistory()
}
/**
+ * Returns status history by id
+ *
* @param mixed $statusId
* @return string|false
*/
@@ -1545,6 +1574,7 @@ public function getStatusHistoryById($statusId)
/**
* Set the order status history object and the order object to each other
+ *
* Adds the object to the status history collection, which is automatically saved when the order is saved.
* See the entity_id attribute backend model.
* Or the history record can be saved standalone after this.
@@ -1564,6 +1594,8 @@ public function addStatusHistory(\Magento\Sales\Model\Order\Status\History $hist
}
/**
+ * Returns real order id
+ *
* @return string
*/
public function getRealOrderId()
@@ -1592,9 +1624,9 @@ public function getOrderCurrency()
/**
* Get formatted price value including order currency rate to order website currency
*
- * @param float $price
- * @param bool $addBrackets
- * @return string
+ * @param float $price
+ * @param bool $addBrackets
+ * @return string
*/
public function formatPrice($price, $addBrackets = false)
{
@@ -1602,6 +1634,8 @@ public function formatPrice($price, $addBrackets = false)
}
/**
+ * Format price precision
+ *
* @param float $price
* @param int $precision
* @param bool $addBrackets
@@ -1615,8 +1649,8 @@ public function formatPricePrecision($price, $precision, $addBrackets = false)
/**
* Retrieve text formatted price value including order rate
*
- * @param float $price
- * @return string
+ * @param float $price
+ * @return string
*/
public function formatPriceTxt($price)
{
@@ -1637,6 +1671,8 @@ public function getBaseCurrency()
}
/**
+ * Format base price
+ *
* @param float $price
* @return string
*/
@@ -1646,6 +1682,8 @@ public function formatBasePrice($price)
}
/**
+ * Format Base Price Precision
+ *
* @param float $price
* @param int $precision
* @return string
@@ -1656,6 +1694,8 @@ public function formatBasePricePrecision($price, $precision)
}
/**
+ * Is Currency Different
+ *
* @return bool
*/
public function isCurrencyDifferent()
@@ -1688,6 +1728,8 @@ public function getBaseTotalDue()
}
/**
+ * Returns object data
+ *
* @param string $key
* @param null|string|int $index
* @return mixed
@@ -1828,6 +1870,8 @@ public function getRelatedObjects()
}
/**
+ * Returns customer name
+ *
* @return string
*/
public function getCustomerName()
@@ -1855,8 +1899,8 @@ public function addRelatedObject(\Magento\Framework\Model\AbstractModel $object)
/**
* Get formatted order created date in store timezone
*
- * @param string $format date format type (short|medium|long|full)
- * @return string
+ * @param string $format date format type (short|medium|long|full)
+ * @return string
*/
public function getCreatedAtFormatted($format)
{
@@ -1870,6 +1914,8 @@ public function getCreatedAtFormatted($format)
}
/**
+ * Returns email customer note
+ *
* @return string
*/
public function getEmailCustomerNote()
@@ -1881,6 +1927,8 @@ public function getEmailCustomerNote()
}
/**
+ * Returns store group name
+ *
* @return string
*/
public function getStoreGroupName()
@@ -1894,7 +1942,8 @@ public function getStoreGroupName()
/**
* Resets all data in object
- * so after another load it will be complete new object
+ *
+ * So after another load it will be complete new object
*
* @return $this
*/
@@ -1918,6 +1967,8 @@ public function reset()
}
/**
+ * Get order is not virtual
+ *
* @return bool
* @SuppressWarnings(PHPMD.BooleanGetMethodName)
*/
@@ -1960,6 +2011,8 @@ public function getIncrementId()
}
/**
+ * Returns order items
+ *
* @return \Magento\Sales\Api\Data\OrderItemInterface[]
*/
public function getItems()
@@ -1974,7 +2027,7 @@ public function getItems()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
* @codeCoverageIgnore
*/
public function setItems($items)
@@ -1983,6 +2036,8 @@ public function setItems($items)
}
/**
+ * Returns order addresses
+ *
* @return \Magento\Sales\Api\Data\OrderAddressInterface[]
*/
public function getAddresses()
@@ -1997,6 +2052,8 @@ public function getAddresses()
}
/**
+ * Returns status history
+ *
* @return \Magento\Sales\Api\Data\OrderStatusHistoryInterface[]|null
*/
public function getStatusHistories()
@@ -2011,7 +2068,7 @@ public function getStatusHistories()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*
* @return \Magento\Sales\Api\Data\OrderExtensionInterface|null
*/
@@ -2021,7 +2078,7 @@ public function getExtensionAttributes()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*
* @param \Magento\Sales\Api\Data\OrderExtensionInterface $extensionAttributes
* @return $this
@@ -2504,7 +2561,7 @@ public function getCreatedAt()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCreatedAt($createdAt)
{
@@ -3322,7 +3379,7 @@ public function getXForwardedFor()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setStatusHistories(array $statusHistories = null)
{
@@ -3330,7 +3387,7 @@ public function setStatusHistories(array $statusHistories = null)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setStatus($status)
{
@@ -3338,7 +3395,7 @@ public function setStatus($status)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCouponCode($code)
{
@@ -3346,7 +3403,7 @@ public function setCouponCode($code)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setProtectCode($code)
{
@@ -3354,7 +3411,7 @@ public function setProtectCode($code)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setShippingDescription($description)
{
@@ -3362,7 +3419,7 @@ public function setShippingDescription($description)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setIsVirtual($isVirtual)
{
@@ -3370,7 +3427,7 @@ public function setIsVirtual($isVirtual)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setStoreId($id)
{
@@ -3378,7 +3435,7 @@ public function setStoreId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerId($id)
{
@@ -3386,7 +3443,7 @@ public function setCustomerId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseDiscountAmount($amount)
{
@@ -3394,7 +3451,7 @@ public function setBaseDiscountAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseDiscountCanceled($baseDiscountCanceled)
{
@@ -3402,7 +3459,7 @@ public function setBaseDiscountCanceled($baseDiscountCanceled)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseDiscountInvoiced($baseDiscountInvoiced)
{
@@ -3410,7 +3467,7 @@ public function setBaseDiscountInvoiced($baseDiscountInvoiced)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseDiscountRefunded($baseDiscountRefunded)
{
@@ -3418,7 +3475,7 @@ public function setBaseDiscountRefunded($baseDiscountRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseGrandTotal($amount)
{
@@ -3426,7 +3483,7 @@ public function setBaseGrandTotal($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseShippingAmount($amount)
{
@@ -3434,7 +3491,7 @@ public function setBaseShippingAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseShippingCanceled($baseShippingCanceled)
{
@@ -3442,7 +3499,7 @@ public function setBaseShippingCanceled($baseShippingCanceled)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseShippingInvoiced($baseShippingInvoiced)
{
@@ -3450,7 +3507,7 @@ public function setBaseShippingInvoiced($baseShippingInvoiced)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseShippingRefunded($baseShippingRefunded)
{
@@ -3458,7 +3515,7 @@ public function setBaseShippingRefunded($baseShippingRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseShippingTaxAmount($amount)
{
@@ -3466,7 +3523,7 @@ public function setBaseShippingTaxAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseShippingTaxRefunded($baseShippingTaxRefunded)
{
@@ -3474,7 +3531,7 @@ public function setBaseShippingTaxRefunded($baseShippingTaxRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseSubtotal($amount)
{
@@ -3482,7 +3539,7 @@ public function setBaseSubtotal($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseSubtotalCanceled($baseSubtotalCanceled)
{
@@ -3490,7 +3547,7 @@ public function setBaseSubtotalCanceled($baseSubtotalCanceled)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseSubtotalInvoiced($baseSubtotalInvoiced)
{
@@ -3498,7 +3555,7 @@ public function setBaseSubtotalInvoiced($baseSubtotalInvoiced)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseSubtotalRefunded($baseSubtotalRefunded)
{
@@ -3506,7 +3563,7 @@ public function setBaseSubtotalRefunded($baseSubtotalRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTaxAmount($amount)
{
@@ -3514,7 +3571,7 @@ public function setBaseTaxAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTaxCanceled($baseTaxCanceled)
{
@@ -3522,7 +3579,7 @@ public function setBaseTaxCanceled($baseTaxCanceled)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTaxInvoiced($baseTaxInvoiced)
{
@@ -3530,7 +3587,7 @@ public function setBaseTaxInvoiced($baseTaxInvoiced)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTaxRefunded($baseTaxRefunded)
{
@@ -3538,7 +3595,7 @@ public function setBaseTaxRefunded($baseTaxRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseToGlobalRate($rate)
{
@@ -3546,7 +3603,7 @@ public function setBaseToGlobalRate($rate)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseToOrderRate($rate)
{
@@ -3554,7 +3611,7 @@ public function setBaseToOrderRate($rate)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTotalCanceled($baseTotalCanceled)
{
@@ -3562,7 +3619,7 @@ public function setBaseTotalCanceled($baseTotalCanceled)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTotalInvoiced($baseTotalInvoiced)
{
@@ -3570,7 +3627,7 @@ public function setBaseTotalInvoiced($baseTotalInvoiced)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTotalInvoicedCost($baseTotalInvoicedCost)
{
@@ -3578,7 +3635,7 @@ public function setBaseTotalInvoicedCost($baseTotalInvoicedCost)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTotalOfflineRefunded($baseTotalOfflineRefunded)
{
@@ -3586,7 +3643,7 @@ public function setBaseTotalOfflineRefunded($baseTotalOfflineRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTotalOnlineRefunded($baseTotalOnlineRefunded)
{
@@ -3594,7 +3651,7 @@ public function setBaseTotalOnlineRefunded($baseTotalOnlineRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTotalPaid($baseTotalPaid)
{
@@ -3602,7 +3659,7 @@ public function setBaseTotalPaid($baseTotalPaid)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTotalQtyOrdered($baseTotalQtyOrdered)
{
@@ -3610,7 +3667,7 @@ public function setBaseTotalQtyOrdered($baseTotalQtyOrdered)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTotalRefunded($baseTotalRefunded)
{
@@ -3618,7 +3675,7 @@ public function setBaseTotalRefunded($baseTotalRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setDiscountAmount($amount)
{
@@ -3626,7 +3683,7 @@ public function setDiscountAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setDiscountCanceled($discountCanceled)
{
@@ -3634,7 +3691,7 @@ public function setDiscountCanceled($discountCanceled)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setDiscountInvoiced($discountInvoiced)
{
@@ -3642,7 +3699,7 @@ public function setDiscountInvoiced($discountInvoiced)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setDiscountRefunded($discountRefunded)
{
@@ -3650,7 +3707,7 @@ public function setDiscountRefunded($discountRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setGrandTotal($amount)
{
@@ -3658,7 +3715,7 @@ public function setGrandTotal($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setShippingAmount($amount)
{
@@ -3666,7 +3723,7 @@ public function setShippingAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setShippingCanceled($shippingCanceled)
{
@@ -3674,7 +3731,7 @@ public function setShippingCanceled($shippingCanceled)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setShippingInvoiced($shippingInvoiced)
{
@@ -3682,7 +3739,7 @@ public function setShippingInvoiced($shippingInvoiced)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setShippingRefunded($shippingRefunded)
{
@@ -3690,7 +3747,7 @@ public function setShippingRefunded($shippingRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setShippingTaxAmount($amount)
{
@@ -3698,7 +3755,7 @@ public function setShippingTaxAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setShippingTaxRefunded($shippingTaxRefunded)
{
@@ -3706,7 +3763,7 @@ public function setShippingTaxRefunded($shippingTaxRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setStoreToBaseRate($rate)
{
@@ -3714,7 +3771,7 @@ public function setStoreToBaseRate($rate)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setStoreToOrderRate($rate)
{
@@ -3722,7 +3779,7 @@ public function setStoreToOrderRate($rate)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setSubtotal($amount)
{
@@ -3730,7 +3787,7 @@ public function setSubtotal($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setSubtotalCanceled($subtotalCanceled)
{
@@ -3738,7 +3795,7 @@ public function setSubtotalCanceled($subtotalCanceled)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setSubtotalInvoiced($subtotalInvoiced)
{
@@ -3746,7 +3803,7 @@ public function setSubtotalInvoiced($subtotalInvoiced)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setSubtotalRefunded($subtotalRefunded)
{
@@ -3754,7 +3811,7 @@ public function setSubtotalRefunded($subtotalRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTaxAmount($amount)
{
@@ -3762,7 +3819,7 @@ public function setTaxAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTaxCanceled($taxCanceled)
{
@@ -3770,7 +3827,7 @@ public function setTaxCanceled($taxCanceled)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTaxInvoiced($taxInvoiced)
{
@@ -3778,7 +3835,7 @@ public function setTaxInvoiced($taxInvoiced)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTaxRefunded($taxRefunded)
{
@@ -3786,7 +3843,7 @@ public function setTaxRefunded($taxRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTotalCanceled($totalCanceled)
{
@@ -3794,7 +3851,7 @@ public function setTotalCanceled($totalCanceled)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTotalInvoiced($totalInvoiced)
{
@@ -3802,7 +3859,7 @@ public function setTotalInvoiced($totalInvoiced)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTotalOfflineRefunded($totalOfflineRefunded)
{
@@ -3810,7 +3867,7 @@ public function setTotalOfflineRefunded($totalOfflineRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTotalOnlineRefunded($totalOnlineRefunded)
{
@@ -3818,7 +3875,7 @@ public function setTotalOnlineRefunded($totalOnlineRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTotalPaid($totalPaid)
{
@@ -3826,7 +3883,7 @@ public function setTotalPaid($totalPaid)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTotalQtyOrdered($totalQtyOrdered)
{
@@ -3834,7 +3891,7 @@ public function setTotalQtyOrdered($totalQtyOrdered)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTotalRefunded($totalRefunded)
{
@@ -3842,7 +3899,7 @@ public function setTotalRefunded($totalRefunded)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCanShipPartially($flag)
{
@@ -3850,7 +3907,7 @@ public function setCanShipPartially($flag)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCanShipPartiallyItem($flag)
{
@@ -3858,7 +3915,7 @@ public function setCanShipPartiallyItem($flag)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerIsGuest($customerIsGuest)
{
@@ -3866,7 +3923,7 @@ public function setCustomerIsGuest($customerIsGuest)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerNoteNotify($customerNoteNotify)
{
@@ -3874,7 +3931,7 @@ public function setCustomerNoteNotify($customerNoteNotify)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBillingAddressId($id)
{
@@ -3882,7 +3939,7 @@ public function setBillingAddressId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerGroupId($id)
{
@@ -3890,7 +3947,7 @@ public function setCustomerGroupId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setEditIncrement($editIncrement)
{
@@ -3898,7 +3955,7 @@ public function setEditIncrement($editIncrement)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setEmailSent($emailSent)
{
@@ -3906,7 +3963,7 @@ public function setEmailSent($emailSent)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setForcedShipmentWithInvoice($forcedShipmentWithInvoice)
{
@@ -3914,7 +3971,7 @@ public function setForcedShipmentWithInvoice($forcedShipmentWithInvoice)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setPaymentAuthExpiration($paymentAuthExpiration)
{
@@ -3922,7 +3979,7 @@ public function setPaymentAuthExpiration($paymentAuthExpiration)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setQuoteAddressId($id)
{
@@ -3930,7 +3987,7 @@ public function setQuoteAddressId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setQuoteId($id)
{
@@ -3938,7 +3995,7 @@ public function setQuoteId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setAdjustmentNegative($adjustmentNegative)
{
@@ -3946,7 +4003,7 @@ public function setAdjustmentNegative($adjustmentNegative)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setAdjustmentPositive($adjustmentPositive)
{
@@ -3954,7 +4011,7 @@ public function setAdjustmentPositive($adjustmentPositive)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseAdjustmentNegative($baseAdjustmentNegative)
{
@@ -3962,7 +4019,7 @@ public function setBaseAdjustmentNegative($baseAdjustmentNegative)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseAdjustmentPositive($baseAdjustmentPositive)
{
@@ -3970,7 +4027,7 @@ public function setBaseAdjustmentPositive($baseAdjustmentPositive)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseShippingDiscountAmount($amount)
{
@@ -3978,7 +4035,7 @@ public function setBaseShippingDiscountAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseSubtotalInclTax($amount)
{
@@ -3986,7 +4043,7 @@ public function setBaseSubtotalInclTax($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseTotalDue($baseTotalDue)
{
@@ -3994,7 +4051,7 @@ public function setBaseTotalDue($baseTotalDue)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setPaymentAuthorizationAmount($amount)
{
@@ -4002,7 +4059,7 @@ public function setPaymentAuthorizationAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setShippingDiscountAmount($amount)
{
@@ -4010,7 +4067,7 @@ public function setShippingDiscountAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setSubtotalInclTax($amount)
{
@@ -4018,7 +4075,7 @@ public function setSubtotalInclTax($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTotalDue($totalDue)
{
@@ -4026,7 +4083,7 @@ public function setTotalDue($totalDue)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setWeight($weight)
{
@@ -4034,7 +4091,7 @@ public function setWeight($weight)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerDob($customerDob)
{
@@ -4042,7 +4099,7 @@ public function setCustomerDob($customerDob)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setIncrementId($id)
{
@@ -4050,7 +4107,7 @@ public function setIncrementId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setAppliedRuleIds($appliedRuleIds)
{
@@ -4058,7 +4115,7 @@ public function setAppliedRuleIds($appliedRuleIds)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseCurrencyCode($code)
{
@@ -4066,7 +4123,7 @@ public function setBaseCurrencyCode($code)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerEmail($customerEmail)
{
@@ -4074,7 +4131,7 @@ public function setCustomerEmail($customerEmail)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerFirstname($customerFirstname)
{
@@ -4082,7 +4139,7 @@ public function setCustomerFirstname($customerFirstname)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerLastname($customerLastname)
{
@@ -4090,7 +4147,7 @@ public function setCustomerLastname($customerLastname)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerMiddlename($customerMiddlename)
{
@@ -4098,7 +4155,7 @@ public function setCustomerMiddlename($customerMiddlename)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerPrefix($customerPrefix)
{
@@ -4106,7 +4163,7 @@ public function setCustomerPrefix($customerPrefix)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerSuffix($customerSuffix)
{
@@ -4114,7 +4171,7 @@ public function setCustomerSuffix($customerSuffix)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerTaxvat($customerTaxvat)
{
@@ -4122,7 +4179,7 @@ public function setCustomerTaxvat($customerTaxvat)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setDiscountDescription($description)
{
@@ -4130,7 +4187,7 @@ public function setDiscountDescription($description)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setExtCustomerId($id)
{
@@ -4138,7 +4195,7 @@ public function setExtCustomerId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setExtOrderId($id)
{
@@ -4146,7 +4203,7 @@ public function setExtOrderId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setGlobalCurrencyCode($code)
{
@@ -4154,7 +4211,7 @@ public function setGlobalCurrencyCode($code)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setHoldBeforeState($holdBeforeState)
{
@@ -4162,7 +4219,7 @@ public function setHoldBeforeState($holdBeforeState)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setHoldBeforeStatus($holdBeforeStatus)
{
@@ -4170,7 +4227,7 @@ public function setHoldBeforeStatus($holdBeforeStatus)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setOrderCurrencyCode($code)
{
@@ -4178,7 +4235,7 @@ public function setOrderCurrencyCode($code)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setOriginalIncrementId($id)
{
@@ -4186,7 +4243,7 @@ public function setOriginalIncrementId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setRelationChildId($id)
{
@@ -4194,7 +4251,7 @@ public function setRelationChildId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setRelationChildRealId($realId)
{
@@ -4202,7 +4259,7 @@ public function setRelationChildRealId($realId)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setRelationParentId($id)
{
@@ -4210,7 +4267,7 @@ public function setRelationParentId($id)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setRelationParentRealId($realId)
{
@@ -4218,7 +4275,7 @@ public function setRelationParentRealId($realId)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setRemoteIp($remoteIp)
{
@@ -4226,7 +4283,7 @@ public function setRemoteIp($remoteIp)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setStoreCurrencyCode($code)
{
@@ -4234,7 +4291,7 @@ public function setStoreCurrencyCode($code)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setStoreName($storeName)
{
@@ -4242,7 +4299,7 @@ public function setStoreName($storeName)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setXForwardedFor($xForwardedFor)
{
@@ -4250,7 +4307,7 @@ public function setXForwardedFor($xForwardedFor)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerNote($customerNote)
{
@@ -4258,7 +4315,7 @@ public function setCustomerNote($customerNote)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setUpdatedAt($timestamp)
{
@@ -4266,7 +4323,7 @@ public function setUpdatedAt($timestamp)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setTotalItemCount($totalItemCount)
{
@@ -4274,7 +4331,7 @@ public function setTotalItemCount($totalItemCount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setCustomerGender($customerGender)
{
@@ -4282,7 +4339,7 @@ public function setCustomerGender($customerGender)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setDiscountTaxCompensationAmount($amount)
{
@@ -4290,7 +4347,7 @@ public function setDiscountTaxCompensationAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseDiscountTaxCompensationAmount($amount)
{
@@ -4298,7 +4355,7 @@ public function setBaseDiscountTaxCompensationAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setShippingDiscountTaxCompensationAmount($amount)
{
@@ -4306,7 +4363,7 @@ public function setShippingDiscountTaxCompensationAmount($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseShippingDiscountTaxCompensationAmnt($amnt)
{
@@ -4314,7 +4371,7 @@ public function setBaseShippingDiscountTaxCompensationAmnt($amnt)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setDiscountTaxCompensationInvoiced($discountTaxCompensationInvoiced)
{
@@ -4322,7 +4379,7 @@ public function setDiscountTaxCompensationInvoiced($discountTaxCompensationInvoi
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseDiscountTaxCompensationInvoiced($baseDiscountTaxCompensationInvoiced)
{
@@ -4333,7 +4390,7 @@ public function setBaseDiscountTaxCompensationInvoiced($baseDiscountTaxCompensat
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setDiscountTaxCompensationRefunded($discountTaxCompensationRefunded)
{
@@ -4344,7 +4401,7 @@ public function setDiscountTaxCompensationRefunded($discountTaxCompensationRefun
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseDiscountTaxCompensationRefunded($baseDiscountTaxCompensationRefunded)
{
@@ -4355,7 +4412,7 @@ public function setBaseDiscountTaxCompensationRefunded($baseDiscountTaxCompensat
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setShippingInclTax($amount)
{
@@ -4363,7 +4420,7 @@ public function setShippingInclTax($amount)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function setBaseShippingInclTax($amount)
{
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender.php b/app/code/Magento/Sales/Model/Order/Email/Sender.php
index 6d4480c4c45..564fd1e2a4b 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender.php
@@ -65,6 +65,8 @@ public function __construct(
}
/**
+ * Send order email if it is enabled in configuration.
+ *
* @param Order $order
* @return bool
*/
@@ -81,17 +83,21 @@ protected function checkAndSend(Order $order)
try {
$sender->send();
- $sender->sendCopyTo();
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
-
return false;
}
-
+ try {
+ $sender->sendCopyTo();
+ } catch (\Exception $e) {
+ $this->logger->error($e->getMessage());
+ }
return true;
}
/**
+ * Populate order email template with customer information.
+ *
* @param Order $order
* @return void
*/
@@ -113,6 +119,8 @@ protected function prepareTemplate(Order $order)
}
/**
+ * Create Sender object using appropriate template and identity.
+ *
* @return Sender
*/
protected function getSender()
@@ -126,6 +134,8 @@ protected function getSender()
}
/**
+ * Get template options.
+ *
* @return array
*/
protected function getTemplateOptions()
@@ -137,6 +147,8 @@ protected function getTemplateOptions()
}
/**
+ * Render shipping address into html.
+ *
* @param Order $order
* @return string|null
*/
@@ -148,6 +160,8 @@ protected function getFormattedShippingAddress($order)
}
/**
+ * Render billing address into html.
+ *
* @param Order $order
* @return string|null
*/
diff --git a/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php b/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php
index 401fdcd2b04..85e34f560bb 100644
--- a/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php
+++ b/app/code/Magento/Sales/Model/Order/Pdf/AbstractPdf.php
@@ -158,8 +158,7 @@ public function __construct(
}
/**
- * Returns the total width in points of the string using the specified font and
- * size.
+ * Returns the total width in points of the string using the specified font and size.
*
* This is not the most efficient way to perform this calculation. I'm
* concentrating optimization efforts on the upcoming layout manager class.
@@ -230,7 +229,7 @@ public function getAlignCenter($string, $x, $columnWidth, \Zend_Pdf_Resource_Fon
* Insert logo to pdf page
*
* @param \Zend_Pdf_Page &$page
- * @param null $store
+ * @param string|null $store
* @return void
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
@@ -285,7 +284,7 @@ protected function insertLogo(&$page, $store = null)
* Insert address to pdf page
*
* @param \Zend_Pdf_Page &$page
- * @param null $store
+ * @param string|null $store
* @return void
*/
protected function insertAddress(&$page, $store = null)
@@ -641,11 +640,7 @@ protected function _sortTotalsList($a, $b)
return 0;
}
- if ($a['sort_order'] == $b['sort_order']) {
- return 0;
- }
-
- return $a['sort_order'] > $b['sort_order'] ? 1 : -1;
+ return $a['sort_order'] <=> $b['sort_order'];
}
/**
diff --git a/app/code/Magento/Sales/Model/Order/Status.php b/app/code/Magento/Sales/Model/Order/Status.php
index 28895570542..4b33f4b4d92 100644
--- a/app/code/Magento/Sales/Model/Order/Status.php
+++ b/app/code/Magento/Sales/Model/Order/Status.php
@@ -12,6 +12,7 @@
* Class Status
*
* @method string getStatus()
+ * @method $this setStatus(string $status)
* @method string getLabel()
*/
class Status extends \Magento\Sales\Model\AbstractModel
diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Collection.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Collection.php
index f004a1ee37e..8758fc1da92 100644
--- a/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Collection.php
+++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Shipment/Collection.php
@@ -57,14 +57,16 @@ protected function _construct()
}
/**
- * Used to emulate after load functionality for each item without loading them
+ * Unserialize packages in each item
*
* @return $this
*/
protected function _afterLoad()
{
- $this->walk('afterLoad');
+ foreach ($this->_items as $item) {
+ $this->getResource()->unserializeFields($item);
+ }
- return $this;
+ return parent::_afterLoad();
}
}
diff --git a/app/code/Magento/Sales/Model/Service/CreditmemoService.php b/app/code/Magento/Sales/Model/Service/CreditmemoService.php
index e8f2e6e5305..bac72e0b522 100644
--- a/app/code/Magento/Sales/Model/Service/CreditmemoService.php
+++ b/app/code/Magento/Sales/Model/Service/CreditmemoService.php
@@ -166,8 +166,8 @@ public function refund(
$creditmemo->getOrder(),
!$offlineRequested
);
- $this->getOrderRepository()->save($order);
$this->creditmemoRepository->save($creditmemo);
+ $this->getOrderRepository()->save($order);
$connection->commit();
} catch (\Exception $e) {
$connection->rollBack();
@@ -178,6 +178,8 @@ public function refund(
}
/**
+ * Validates if credit memo is available for refund.
+ *
* @param \Magento\Sales\Api\Data\CreditmemoInterface $creditmemo
* @return bool
* @throws \Magento\Framework\Exception\LocalizedException
@@ -208,8 +210,9 @@ protected function validateForRefund(\Magento\Sales\Api\Data\CreditmemoInterface
}
/**
- * @return \Magento\Sales\Model\Order\RefundAdapterInterface
+ * Gets the instance of RefundAdapterInterface
*
+ * @return \Magento\Sales\Model\Order\RefundAdapterInterface
* @deprecated 100.1.3
*/
private function getRefundAdapter()
@@ -222,8 +225,9 @@ private function getRefundAdapter()
}
/**
- * @return \Magento\Framework\App\ResourceConnection|mixed
+ * Gets instance of ResourceConnection.
*
+ * @return \Magento\Framework\App\ResourceConnection|mixed
* @deprecated 100.1.3
*/
private function getResource()
@@ -236,8 +240,9 @@ private function getResource()
}
/**
- * @return \Magento\Sales\Api\OrderRepositoryInterface
+ * Gets instance of OrderRepositoryInterface.
*
+ * @return \Magento\Sales\Api\OrderRepositoryInterface
* @deprecated 100.1.3
*/
private function getOrderRepository()
@@ -250,8 +255,9 @@ private function getOrderRepository()
}
/**
- * @return \Magento\Sales\Api\InvoiceRepositoryInterface
+ * Gets instance of InvoiceRepositoryInterface
*
+ * @return \Magento\Sales\Api\InvoiceRepositoryInterface
* @deprecated 100.1.3
*/
private function getInvoiceRepository()
diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderToPrintPageActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderToPrintPageActionGroup.xml
new file mode 100644
index 00000000000..fe2fc49f1d0
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderToPrintPageActionGroup.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Page/StorefrontCustomerSignOutPage.xml b/app/code/Magento/Sales/Test/Mftf/Page/StorefrontCustomerSignOutPage.xml
new file mode 100644
index 00000000000..4e89e5476c3
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Page/StorefrontCustomerSignOutPage.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Page/StorefrontSalesOrderPrintPage.xml b/app/code/Magento/Sales/Test/Mftf/Page/StorefrontSalesOrderPrintPage.xml
new file mode 100644
index 00000000000..874e6889ec5
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Page/StorefrontSalesOrderPrintPage.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicesFiltersSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicesFiltersSection.xml
index 8fb45295bd2..78b9c853ff6 100644
--- a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicesFiltersSection.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicesFiltersSection.xml
@@ -10,5 +10,6 @@
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml
index e4d329bc850..4350ffeb033 100644
--- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderFormPaymentSection.xml
@@ -13,5 +13,6 @@
+
\ No newline at end of file
diff --git a/app/code/Magento/Sales/Test/Mftf/Section/SalesOrderPrintSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/SalesOrderPrintSection.xml
new file mode 100644
index 00000000000..b08a66140fa
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Section/SalesOrderPrintSection.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml
index 05f20371851..82f5b515eb9 100644
--- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml
@@ -78,8 +78,10 @@
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminFreeShippingNotAvailableIfMinimumOrderAmountNotMatchOrderTotalTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminFreeShippingNotAvailableIfMinimumOrderAmountNotMatchOrderTotalTest.xml
new file mode 100644
index 00000000000..5f6ea0937b5
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminFreeShippingNotAvailableIfMinimumOrderAmountNotMatchOrderTotalTest.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 100
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontRedirectToOrderHistory.xml b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontRedirectToOrderHistory.xml
new file mode 100644
index 00000000000..ec725ad5fe4
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontRedirectToOrderHistory.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Unit/Model/ValidatorResultMergerTest.php b/app/code/Magento/Sales/Test/Unit/Model/ValidatorResultMergerTest.php
new file mode 100644
index 00000000000..4236890a2a3
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Unit/Model/ValidatorResultMergerTest.php
@@ -0,0 +1,87 @@
+validatorResultFactoryMock = $this->getMockBuilder(ValidatorResultInterfaceFactory::class)
+ ->setMethods(['create'])->disableOriginalConstructor()->getMock();
+ $this->objectManager = new ObjectManager($this);
+ $this->validatorResultMerger = $this->objectManager->getObject(
+ ValidatorResultMerger::class,
+ [
+ 'validatorResultInterfaceFactory' => $this->validatorResultFactoryMock,
+ ]
+ );
+ }
+
+ /**
+ * Test merge method
+ *
+ * @return void
+ */
+ public function testMerge()
+ {
+ $validatorResultMock = $this->createMock(ValidatorResultInterface::class);
+ $orderValidationResultMock = $this->createMock(ValidatorResultInterface::class);
+ $creditmemoValidationResultMock = $this->createMock(ValidatorResultInterface::class);
+ $itemsValidationMessages = [['test04', 'test05'], ['test06']];
+ $this->validatorResultFactoryMock->expects($this->once())->method('create')
+ ->willReturn($validatorResultMock);
+ $orderValidationResultMock->expects($this->once())->method('getMessages')->willReturn(['test01', 'test02']);
+ $creditmemoValidationResultMock->expects($this->once())->method('getMessages')->willReturn(['test03']);
+
+ $validatorResultMock->expects($this->at(0))->method('addMessage')->with('test01');
+ $validatorResultMock->expects($this->at(1))->method('addMessage')->with('test02');
+ $validatorResultMock->expects($this->at(2))->method('addMessage')->with('test03');
+ $validatorResultMock->expects($this->at(3))->method('addMessage')->with('test04');
+ $validatorResultMock->expects($this->at(4))->method('addMessage')->with('test05');
+ $validatorResultMock->expects($this->at(5))->method('addMessage')->with('test06');
+ $expected = $validatorResultMock;
+ $actual = $this->validatorResultMerger->merge(
+ $orderValidationResultMock,
+ $creditmemoValidationResultMock,
+ ...$itemsValidationMessages
+ );
+ $this->assertEquals($expected, $actual);
+ }
+}
diff --git a/app/code/Magento/Sales/Test/Unit/Model/ValidatorResultTest.php b/app/code/Magento/Sales/Test/Unit/Model/ValidatorResultTest.php
new file mode 100644
index 00000000000..f4ab2d4f48e
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Unit/Model/ValidatorResultTest.php
@@ -0,0 +1,75 @@
+objectManager = new ObjectManager($this);
+ $this->validatorResult = $this->objectManager->getObject(ValidatorResult::class);
+ }
+
+ /**
+ * Test addMessage method
+ *
+ * @return void
+ */
+ public function testAddMessages()
+ {
+ $messageFirst = 'Sample message 01.';
+ $messageSecond = 'Sample messages 02.';
+ $messageThird = 'Sample messages 03.';
+ $expected = [$messageFirst, $messageSecond, $messageThird];
+ $this->validatorResult->addMessage($messageFirst);
+ $this->validatorResult->addMessage($messageSecond);
+ $this->validatorResult->addMessage($messageThird);
+ $actual = $this->validatorResult->getMessages();
+ $this->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Test hasMessages method
+ *
+ * @return void
+ */
+ public function testHasMessages()
+ {
+ $this->assertFalse($this->validatorResult->hasMessages());
+ $messageFirst = 'Sample message 01.';
+ $messageSecond = 'Sample messages 02.';
+ $this->validatorResult->addMessage($messageFirst);
+ $this->validatorResult->addMessage($messageSecond);
+ $this->assertTrue($this->validatorResult->hasMessages());
+ }
+}
diff --git a/app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php b/app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php
new file mode 100644
index 00000000000..c6e02151b9b
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Unit/Observer/AssignOrderToCustomerObserverTest.php
@@ -0,0 +1,91 @@
+orderRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->sut = new AssignOrderToCustomerObserver($this->orderRepositoryMock);
+ }
+
+ /**
+ * Test assigning order to customer after issuing guest order
+ *
+ * @dataProvider getCustomerIds
+ * @param null|int $customerId
+ * @return void
+ */
+ public function testAssignOrderToCustomerAfterGuestOrder($customerId)
+ {
+ $orderId = 1;
+ /** @var Observer|PHPUnit_Framework_MockObject_MockObject $observerMock */
+ $observerMock = $this->createMock(Observer::class);
+ /** @var Event|PHPUnit_Framework_MockObject_MockObject $eventMock */
+ $eventMock = $this->getMockBuilder(Event::class)->disableOriginalConstructor()
+ ->setMethods(['getData'])
+ ->getMock();
+ /** @var CustomerInterface|PHPUnit_Framework_MockObject_MockObject $customerMock */
+ $customerMock = $this->createMock(CustomerInterface::class);
+ /** @var OrderInterface|PHPUnit_Framework_MockObject_MockObject $orderMock */
+ $orderMock = $this->getMockBuilder(OrderInterface::class)
+ ->disableOriginalConstructor()
+ ->getMockForAbstractClass();
+ $observerMock->expects($this->once())->method('getEvent')->willReturn($eventMock);
+ $eventMock->expects($this->any())->method('getData')
+ ->willReturnMap([
+ ['delegate_data', null, ['__sales_assign_order_id' => $orderId]],
+ ['customer_data_object', null, $customerMock]
+ ]);
+ $orderMock->expects($this->once())->method('getCustomerId')->willReturn($customerId);
+ $this->orderRepositoryMock->expects($this->once())->method('get')->with($orderId)
+ ->willReturn($orderMock);
+ if (!$customerId) {
+ $this->orderRepositoryMock->expects($this->once())->method('save')->with($orderMock);
+ $this->sut->execute($observerMock);
+ return ;
+ }
+
+ $this->orderRepositoryMock->expects($this->never())->method('save')->with($orderMock);
+ $this->sut->execute($observerMock);
+ }
+
+ /**
+ * Customer id assigned to order
+ *
+ * @return array
+ */
+ public function getCustomerIds()
+ {
+ return [[null, 1]];
+ }
+}
diff --git a/app/code/Magento/Sales/etc/db_schema.xml b/app/code/Magento/Sales/etc/db_schema.xml
index 4b716e76109..fda6e75cf00 100644
--- a/app/code/Magento/Sales/etc/db_schema.xml
+++ b/app/code/Magento/Sales/etc/db_schema.xml
@@ -9,7 +9,7 @@
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
+ comment="Entity ID"/>
@@ -297,13 +297,13 @@
+ comment="Entity ID"/>
+ comment="Store ID"/>
+ comment="Customer ID"/>
+ comment="Entity ID"/>
+ comment="Parent ID"/>
+ comment="Customer Address ID"/>
+ comment="Quote Address ID"/>
+ comment="Region ID"/>
+ comment="Customer ID"/>
@@ -431,9 +431,9 @@
+ comment="Entity ID"/>
+ comment="Parent ID"/>
+ comment="Entity ID"/>
+ comment="Parent ID"/>
+ comment="Entity ID"/>
+ comment="Store ID"/>
+ comment="Order ID"/>
+ comment="Customer ID"/>
+ comment="Shipping Address ID"/>
+ comment="Billing Address ID"/>
@@ -762,13 +762,13 @@
+ comment="Entity ID"/>
+ comment="Store ID"/>
+ comment="Order ID"/>
@@ -837,9 +837,9 @@
+ comment="Entity ID"/>
+ comment="Parent ID"/>
+ comment="Product ID"/>
+ comment="Order Item ID"/>
@@ -867,14 +867,14 @@
+ comment="Entity ID"/>
+ comment="Parent ID"/>
+ comment="Order ID"/>
@@ -901,9 +901,9 @@
+ comment="Entity ID"/>
+ comment="Parent ID"/>
+ comment="Entity ID"/>
+ comment="Store ID"/>
+ comment="Entity ID"/>
+ comment="Store ID"/>
+ comment="Order ID"/>
@@ -1136,9 +1136,9 @@
+ comment="Entity ID"/>
+ comment="Parent ID"/>
+ comment="Entity ID"/>
+ comment="Parent ID"/>
+ comment="Entity ID"/>
+ comment="Store ID"/>
+ comment="Entity ID"/>
+ comment="Order ID"/>
@@ -1366,7 +1366,7 @@
comment="Base Grand Total"/>
+ comment="Store ID"/>
@@ -1438,9 +1438,9 @@
+ comment="Entity ID"/>
+ comment="Parent ID"/>
+ comment="Product ID"/>
+ comment="Order Item ID"/>
@@ -1494,9 +1494,9 @@
+ comment="Entity ID"/>
+ comment="Parent ID"/>
' + this._label + '');
content[position] = node;
Element.insert(element, content);
+ },
+
+ getLabel: function(){
+ return this._label;
}
};
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_guest_print.xml b/app/code/Magento/Sales/view/frontend/layout/sales_guest_print.xml
index 0e2689e3e21..99af16ce629 100644
--- a/app/code/Magento/Sales/view/frontend/layout/sales_guest_print.xml
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_guest_print.xml
@@ -12,11 +12,20 @@
-
-
+
+
-
+
diff --git a/app/code/Magento/Sales/view/frontend/layout/sales_order_print.xml b/app/code/Magento/Sales/view/frontend/layout/sales_order_print.xml
index 50ffe979651..4410a6fc4a9 100644
--- a/app/code/Magento/Sales/view/frontend/layout/sales_order_print.xml
+++ b/app/code/Magento/Sales/view/frontend/layout/sales_order_print.xml
@@ -12,12 +12,21 @@
-
-
+
+
-
-
+
+
diff --git a/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/DeleteButton.php b/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/DeleteButton.php
index 0cb286056d8..bee7573c1fe 100644
--- a/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/DeleteButton.php
+++ b/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit/DeleteButton.php
@@ -26,7 +26,7 @@ public function getButtonData()
'class' => 'delete',
'on_click' => 'deleteConfirm(\'' . __(
'Are you sure you want to delete this?'
- ) . '\', \'' . $this->urlBuilder->getUrl('*/*/delete', ['id' => $ruleId]) . '\')',
+ ) . '\', \'' . $this->urlBuilder->getUrl('*/*/delete', ['id' => $ruleId]) . '\', {data: {}})',
'sort_order' => 20,
];
}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
index 28993e15949..45b717fb9bd 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
@@ -6,7 +6,9 @@
*/
namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
-class Delete extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+use Magento\Framework\App\Action\HttpPostActionInterface;
+
+class Delete extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote implements HttpPostActionInterface
{
/**
* Delete promo quote action
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php
index 717c71fde48..3255ee0f2b7 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php
@@ -6,7 +6,9 @@
*/
namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
-class Edit extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Edit extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote implements HttpGetActionInterface
{
/**
* @var \Magento\Framework\View\Result\PageFactory
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Index.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Index.php
index 0c11ee3785a..4f3c712049e 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Index.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
-class Index extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote implements HttpGetActionInterface
{
/**
* Index action
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewAction.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewAction.php
index ecf39605a87..5adef0552bc 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewAction.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewAction.php
@@ -6,7 +6,9 @@
*/
namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
-class NewAction extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class NewAction extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote implements HttpGetActionInterface
{
/**
* New promo quote action
diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/ApplyCartRuleOnStorefrontActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/ApplyCartRuleOnStorefrontActionGroup.xml
index 55b2e9c10fd..37e171823b1 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/ApplyCartRuleOnStorefrontActionGroup.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/ApplyCartRuleOnStorefrontActionGroup.xml
@@ -9,20 +9,16 @@
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml
index 6ebc78a6771..dbca35d6432 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Data/SalesRuleData.xml
@@ -60,4 +60,32 @@
Percent of product price discount
50
+
+ SimpleSalesRule
+ Sales Rule Descritpion
+
+ - 1
+
+
+ - 0
+ - 1
+ - 3
+
+ 1
+ true
+ false
+ true
+ 2
+ by_percent
+ 10
+ 1
+ 0
+ false
+ 1
+ false
+ SPECIFIC_COUPON
+ true
+ 2
+ 1
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/DiscountSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/DiscountSection.xml
index cbab097c529..e14bfb554b3 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Section/DiscountSection.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Section/DiscountSection.xml
@@ -8,8 +8,9 @@
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontAutoGeneratedCouponCodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontAutoGeneratedCouponCodeTest.xml
new file mode 100644
index 00000000000..6f9474278bf
--- /dev/null
+++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontAutoGeneratedCouponCodeTest.xml
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/SalesRule/Test/Unit/Block/Adminhtml/Promo/Quote/Edit/DeleteButtonTest.php b/app/code/Magento/SalesRule/Test/Unit/Block/Adminhtml/Promo/Quote/Edit/DeleteButtonTest.php
index fb01476ed6b..7812444c686 100644
--- a/app/code/Magento/SalesRule/Test/Unit/Block/Adminhtml/Promo/Quote/Edit/DeleteButtonTest.php
+++ b/app/code/Magento/SalesRule/Test/Unit/Block/Adminhtml/Promo/Quote/Edit/DeleteButtonTest.php
@@ -25,13 +25,16 @@ class DeleteButtonTest extends \PHPUnit\Framework\TestCase
*/
protected $registryMock;
+ /**
+ * @inheritDoc
+ */
protected function setUp()
{
$this->urlBuilderMock = $this->createMock(\Magento\Framework\UrlInterface::class);
$this->registryMock = $this->createMock(\Magento\Framework\Registry::class);
$contextMock = $this->createMock(\Magento\Backend\Block\Widget\Context::class);
- $contextMock->expects($this->once())->method('getUrlBuilder')->willReturn($this->urlBuilderMock);
+ $contextMock->expects($this->any())->method('getUrlBuilder')->willReturn($this->urlBuilderMock);
$this->model = (new ObjectManager($this))->getObject(
\Magento\SalesRule\Block\Adminhtml\Promo\Quote\Edit\DeleteButton::class,
@@ -42,33 +45,9 @@ protected function setUp()
);
}
- public function testGetButtonData()
- {
- $ruleId = 42;
- $deleteUrl = 'http://magento.com/rule/delete/' . $ruleId;
- $ruleMock = new \Magento\Framework\DataObject(['id' => $ruleId]);
-
- $this->registryMock->expects($this->once())
- ->method('registry')
- ->with(RegistryConstants::CURRENT_SALES_RULE)
- ->willReturn($ruleMock);
- $this->urlBuilderMock->expects($this->once())
- ->method('getUrl')
- ->with('*/*/delete', ['id' => $ruleId])
- ->willReturn($deleteUrl);
-
- $data = [
- 'label' => __('Delete'),
- 'class' => 'delete',
- 'on_click' => 'deleteConfirm(\'' . __(
- 'Are you sure you want to delete this?'
- ) . '\', \'' . $deleteUrl . '\')',
- 'sort_order' => 20,
- ];
-
- $this->assertEquals($data, $this->model->getButtonData());
- }
-
+ /**
+ * Test empty response without a present rule.
+ */
public function testGetButtonDataWithoutRule()
{
$this->assertEquals([], $this->model->getButtonData());
diff --git a/app/code/Magento/SalesRule/etc/db_schema.xml b/app/code/Magento/SalesRule/etc/db_schema.xml
index 3d882ee2eae..145ed0c96d9 100644
--- a/app/code/Magento/SalesRule/etc/db_schema.xml
+++ b/app/code/Magento/SalesRule/etc/db_schema.xml
@@ -9,7 +9,7 @@
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
+ comment="Entity ID"/>
@@ -60,7 +60,7 @@
+ comment="Rule ID"/>
@@ -117,7 +117,7 @@
+ comment="Rule ID"/>
+ comment="Rule ID"/>
@@ -163,7 +163,8 @@
-
+
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/Delete.php b/app/code/Magento/Search/Controller/Adminhtml/Term/Delete.php
index c7adf32da0f..ce3dfcc601f 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/Delete.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/Delete.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Search\Controller\Adminhtml\Term;
+use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Search\Controller\Adminhtml\Term as TermController;
use Magento\Framework\Controller\ResultFactory;
-class Delete extends TermController
+class Delete extends TermController implements HttpPostActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Redirect
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/Edit.php b/app/code/Magento/Search/Controller/Adminhtml/Term/Edit.php
index 3ee0ea24037..cd1ef7553c7 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/Edit.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/Edit.php
@@ -5,12 +5,13 @@
*/
namespace Magento\Search\Controller\Adminhtml\Term;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Search\Controller\Adminhtml\Term as TermController;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Registry;
use Magento\Framework\Controller\ResultFactory;
-class Edit extends TermController
+class Edit extends TermController implements HttpGetActionInterface
{
/**
* Core registry
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/Index.php b/app/code/Magento/Search/Controller/Adminhtml/Term/Index.php
index f7d0b865907..c097cc08489 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/Index.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/Index.php
@@ -5,9 +5,10 @@
*/
namespace Magento\Search\Controller\Adminhtml\Term;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Search\Controller\Adminhtml\Term as TermController;
-class Index extends TermController
+class Index extends TermController implements HttpGetActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Page
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/MassDelete.php b/app/code/Magento/Search/Controller/Adminhtml/Term/MassDelete.php
index f6874078f2f..84e475b7275 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/MassDelete.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/MassDelete.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Search\Controller\Adminhtml\Term;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Search\Controller\Adminhtml\Term as TermController;
use Magento\Framework\Controller\ResultFactory;
-class MassDelete extends TermController
+class MassDelete extends TermController implements HttpPostActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Redirect
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/NewAction.php b/app/code/Magento/Search/Controller/Adminhtml/Term/NewAction.php
index 8565c03724c..49805400713 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/NewAction.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/NewAction.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Search\Controller\Adminhtml\Term;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Search\Controller\Adminhtml\Term as TermController;
use Magento\Framework\Controller\ResultFactory;
-class NewAction extends TermController
+class NewAction extends TermController implements HttpGetActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Forward
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/Report.php b/app/code/Magento/Search/Controller/Adminhtml/Term/Report.php
index fb4964717e5..b0ce066f127 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/Report.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/Report.php
@@ -5,10 +5,11 @@
*/
namespace Magento\Search\Controller\Adminhtml\Term;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Reports\Controller\Adminhtml\Index as ReportsIndexController;
use Magento\Framework\Controller\ResultFactory;
-class Report extends ReportsIndexController
+class Report extends ReportsIndexController implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php b/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php
index cd9b1347ed1..39ae07f0d35 100644
--- a/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php
+++ b/app/code/Magento/Search/Controller/Adminhtml/Term/Save.php
@@ -5,13 +5,14 @@
*/
namespace Magento\Search\Controller\Adminhtml\Term;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use Magento\Search\Model\QueryFactory;
use Magento\Search\Controller\Adminhtml\Term as TermController;
use Magento\Framework\Exception\LocalizedException;
-class Save extends TermController
+class Save extends TermController implements HttpPostActionInterface
{
/**
* @var QueryFactory
diff --git a/app/code/Magento/Search/Controller/Ajax/Suggest.php b/app/code/Magento/Search/Controller/Ajax/Suggest.php
index 307f4df1632..6eab0949145 100644
--- a/app/code/Magento/Search/Controller/Ajax/Suggest.php
+++ b/app/code/Magento/Search/Controller/Ajax/Suggest.php
@@ -5,12 +5,13 @@
*/
namespace Magento\Search\Controller\Ajax;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Search\Model\AutocompleteInterface;
use Magento\Framework\Controller\ResultFactory;
-class Suggest extends Action
+class Suggest extends Action implements HttpGetActionInterface
{
/**
* @var \Magento\Search\Model\AutocompleteInterface
diff --git a/app/code/Magento/Search/view/frontend/web/js/form-mini.js b/app/code/Magento/Search/view/frontend/web/js/form-mini.js
index 86d430041d7..15bcf2e7339 100644
--- a/app/code/Magento/Search/view/frontend/web/js/form-mini.js
+++ b/app/code/Magento/Search/view/frontend/web/js/form-mini.js
@@ -306,12 +306,13 @@ define([
dropdown.append(html);
});
+ this._resetResponseList(true);
+
this.responseList.indexList = this.autoComplete.html(dropdown)
.css(clonePosition)
.show()
.find(this.options.responseFieldElements + ':visible');
- this._resetResponseList(false);
this.element.removeAttr('aria-activedescendant');
if (this.responseList.indexList.length) {
@@ -338,6 +339,11 @@ define([
this._resetResponseList(false);
}
}.bind(this));
+ } else {
+ this._resetResponseList(true);
+ this.autoComplete.hide();
+ this._updateAriaHasPopup(false);
+ this.element.removeAttr('aria-activedescendant');
}
}, this));
} else {
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/NewAction.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/NewAction.php
index be0555fbcda..7231bc8b9c6 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/NewAction.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/NewAction.php
@@ -6,10 +6,11 @@
*/
namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Backend\App\Action;
use Magento\Framework\App\ObjectManager;
-class NewAction extends \Magento\Backend\App\Action
+class NewAction extends \Magento\Backend\App\Action implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
index 4804efcc76e..8bd64ccf82d 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
@@ -6,6 +6,7 @@
*/
namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Backend\App\Action;
use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator;
@@ -13,7 +14,7 @@
* Class Save
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class Save extends \Magento\Backend\App\Action
+class Save extends \Magento\Backend\App\Action implements HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Start.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Start.php
index ac15c0accd1..8a874ddc795 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Start.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Start.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
-class Start extends \Magento\Backend\App\Action
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Start extends \Magento\Backend\App\Action implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Shipping/Test/Mftf/Data/FlatRateShippingMethodData.xml b/app/code/Magento/Shipping/Test/Mftf/Data/FlatRateShippingMethodData.xml
index 6c7e5cf1b18..6d877dac5cb 100644
--- a/app/code/Magento/Shipping/Test/Mftf/Data/FlatRateShippingMethodData.xml
+++ b/app/code/Magento/Shipping/Test/Mftf/Data/FlatRateShippingMethodData.xml
@@ -13,6 +13,13 @@
1
+
+
+ flatRateActiveDisable
+
+
+ 0
+
flatRateActiveDefault
diff --git a/app/code/Magento/Shipping/Test/Mftf/Data/FreeShippingMethodData.xml b/app/code/Magento/Shipping/Test/Mftf/Data/FreeShippingMethodData.xml
index 11079553346..512ef8389bb 100644
--- a/app/code/Magento/Shipping/Test/Mftf/Data/FreeShippingMethodData.xml
+++ b/app/code/Magento/Shipping/Test/Mftf/Data/FreeShippingMethodData.xml
@@ -52,4 +52,18 @@
+
+
+ freeShippingSubtotal
+
+
+ 101
+
+
+
+ freeShippingSubtotalDefault
+
+
+ 0
+
diff --git a/app/code/Magento/Signifyd/Model/CaseServices/UpdatingService.php b/app/code/Magento/Signifyd/Model/CaseServices/UpdatingService.php
index 870705db941..168ab67f8cf 100644
--- a/app/code/Magento/Signifyd/Model/CaseServices/UpdatingService.php
+++ b/app/code/Magento/Signifyd/Model/CaseServices/UpdatingService.php
@@ -5,8 +5,8 @@
*/
namespace Magento\Signifyd\Model\CaseServices;
+use Magento\Framework\Api\SimpleDataObjectConverter;
use Magento\Framework\Exception\LocalizedException;
-use Magento\Framework\Exception\NotFoundException;
use Magento\Signifyd\Api\CaseRepositoryInterface;
use Magento\Signifyd\Api\Data\CaseInterface;
use Magento\Signifyd\Model\CommentsHistoryUpdater;
@@ -73,7 +73,6 @@ public function __construct(
* @param CaseInterface $case
* @param array $data
* @return void
- * @throws NotFoundException
* @throws LocalizedException
*/
public function update(CaseInterface $case, array $data)
@@ -111,7 +110,7 @@ private function setCaseData(CaseInterface $case, array $data)
'orderId'
];
foreach ($data as $key => $value) {
- $methodName = 'set' . ucfirst($key);
+ $methodName = 'set' . SimpleDataObjectConverter::snakeCaseToUpperCamelCase($key);
if (!in_array($key, $notResolvedKeys) && method_exists($case, $methodName)) {
call_user_func([$case, $methodName], $value);
}
diff --git a/app/code/Magento/Signifyd/etc/db_schema.xml b/app/code/Magento/Signifyd/etc/db_schema.xml
index 6a31eacbb45..6f41b883c71 100644
--- a/app/code/Magento/Signifyd/etc/db_schema.xml
+++ b/app/code/Magento/Signifyd/etc/db_schema.xml
@@ -37,6 +37,7 @@
diff --git a/app/code/Magento/Sitemap/Block/Adminhtml/Grid/Renderer/Link.php b/app/code/Magento/Sitemap/Block/Adminhtml/Grid/Renderer/Link.php
index ffc2bf5f6d1..b4e54104bdf 100644
--- a/app/code/Magento/Sitemap/Block/Adminhtml/Grid/Renderer/Link.php
+++ b/app/code/Magento/Sitemap/Block/Adminhtml/Grid/Renderer/Link.php
@@ -3,17 +3,15 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-
-/**
- * Sitemap grid link column renderer
- *
- */
namespace Magento\Sitemap\Block\Adminhtml\Grid\Renderer;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Config\Model\Config\Reader\Source\Deployed\DocumentRoot;
use Magento\Framework\App\ObjectManager;
+/**
+ * Sitemap grid link column renderer
+ */
class Link extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
{
/**
@@ -62,6 +60,7 @@ public function render(\Magento\Framework\DataObject $row)
{
/** @var $sitemap \Magento\Sitemap\Model\Sitemap */
$sitemap = $this->_sitemapFactory->create();
+ $sitemap->setStoreId($row->getStoreId());
$url = $this->escapeHtml($sitemap->getSitemapUrl($row->getSitemapPath(), $row->getSitemapFilename()));
$fileName = preg_replace('/^\//', '', $row->getSitemapPath() . $row->getSitemapFilename());
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Index.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Index.php
index 5f2cc805de0..e6823c6070a 100644
--- a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Index.php
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Index.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Sitemap\Controller\Adminhtml\Sitemap;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Backend\App\Action;
-class Index extends \Magento\Sitemap\Controller\Adminhtml\Sitemap
+class Index extends \Magento\Sitemap\Controller\Adminhtml\Sitemap implements HttpGetActionInterface
{
/**
* Index action
diff --git a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml
index 2bff20e0543..8f859ff3cd6 100644
--- a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml
+++ b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml
@@ -41,12 +41,16 @@
- Second Store View
- store123
+ Second Store View
+ store123
1
null
add
store
customStoreGroup
+
+ Store View
+ store2
+
diff --git a/app/code/Magento/Store/Test/Mftf/Data/StoreGroupData.xml b/app/code/Magento/Store/Test/Mftf/Data/StoreGroupData.xml
index 83ca12875d0..7b31623f237 100644
--- a/app/code/Magento/Store/Test/Mftf/Data/StoreGroupData.xml
+++ b/app/code/Magento/Store/Test/Mftf/Data/StoreGroupData.xml
@@ -27,4 +27,8 @@
2
1
+
+ NewStore
+ Base1
+
diff --git a/app/code/Magento/Store/Test/Mftf/Data/StorePaymentMethodsData.xml b/app/code/Magento/Store/Test/Mftf/Data/StorePaymentMethodsData.xml
new file mode 100644
index 00000000000..912399142fa
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Data/StorePaymentMethodsData.xml
@@ -0,0 +1,30 @@
+
+
+
+
+ active
+ orderStatus
+
+
+ 1
+
+
+ processing
+
+
+
+ zeroSubEnable
+ zeroSubOrderStatus
+
+
+ 1
+
+
+ 1
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Data/StoreShippingMethodsData.xml b/app/code/Magento/Store/Test/Mftf/Data/StoreShippingMethodsData.xml
new file mode 100644
index 00000000000..6e3e7ce7eb0
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Data/StoreShippingMethodsData.xml
@@ -0,0 +1,30 @@
+
+
+
+
+ active
+
+
+ 1
+
+
+
+
+ DefaultFreeShipping
+
+
+ 0
+
+
+
+ disableFreeShipping
+
+
+ 1
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Metadata/store_payment_methods-meta.xml b/app/code/Magento/Store/Test/Mftf/Metadata/store_payment_methods-meta.xml
new file mode 100644
index 00000000000..cbad7265cbb
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Metadata/store_payment_methods-meta.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ integer
+
+
+
+
+ integer
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Metadata/store_shipping_methods-meta.xml b/app/code/Magento/Store/Test/Mftf/Metadata/store_shipping_methods-meta.xml
new file mode 100644
index 00000000000..83288ecfdaf
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Metadata/store_shipping_methods-meta.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+ string
+
+
+
+
+
+
+
+
+
+
+
+
+ integer
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/StoreGraphQl/Model/Resolver/Store/StoreConfigDataProvider.php b/app/code/Magento/StoreGraphQl/Model/Resolver/Store/StoreConfigDataProvider.php
index 92926c12e86..8c2d6c36591 100644
--- a/app/code/Magento/StoreGraphQl/Model/Resolver/Store/StoreConfigDataProvider.php
+++ b/app/code/Magento/StoreGraphQl/Model/Resolver/Store/StoreConfigDataProvider.php
@@ -7,10 +7,10 @@
namespace Magento\StoreGraphQl\Model\Resolver\Store;
-use Magento\Store\Api\Data\StoreConfigInterface;
+use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Api\StoreConfigManagerInterface;
-use Magento\Store\Api\StoreRepositoryInterface;
-use Magento\Store\Api\StoreResolverInterface;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Store\Model\StoreManagerInterface;
/**
* StoreConfig field data provider, used for GraphQL request processing.
@@ -23,39 +23,60 @@ class StoreConfigDataProvider
private $storeConfigManager;
/**
- * @var StoreResolverInterface
+ * @var StoreManagerInterface
*/
- private $storeResolver;
+ private $storeManager;
/**
- * @var StoreRepositoryInterface
+ * @var ScopeConfigInterface
*/
- private $storeRepository;
+ private $scopeConfig;
+
+ /**
+ * @var array
+ */
+ private $extendedConfigData;
/**
* @param StoreConfigManagerInterface $storeConfigManager
- * @param StoreResolverInterface $storeResolver
- * @param StoreRepositoryInterface $storeRepository
+ * @param StoreManagerInterface $storeManager
+ * @param ScopeConfigInterface $scopeConfig
+ * @param array $extendedConfigData
*/
public function __construct(
StoreConfigManagerInterface $storeConfigManager,
- StoreResolverInterface $storeResolver,
- StoreRepositoryInterface $storeRepository
+ StoreManagerInterface $storeManager,
+ ScopeConfigInterface $scopeConfig,
+ array $extendedConfigData = []
) {
$this->storeConfigManager = $storeConfigManager;
- $this->storeResolver = $storeResolver;
- $this->storeRepository = $storeRepository;
+ $this->storeManager = $storeManager;
+ $this->scopeConfig = $scopeConfig;
+ $this->extendedConfigData = $extendedConfigData;
+ }
+
+ /**
+ * Get store config data
+ *
+ * @return array
+ */
+ public function getStoreConfigData(): array
+ {
+ $storeConfigData = array_merge(
+ $this->getBaseConfigData(),
+ $this->getExtendedConfigData()
+ );
+ return $storeConfigData;
}
/**
- * Get store config for current store
+ * Get base config data
*
* @return array
*/
- public function getStoreConfig() : array
+ private function getBaseConfigData() : array
{
- $storeId = $this->storeResolver->getCurrentStoreId();
- $store = $this->storeRepository->getById($storeId);
+ $store = $this->storeManager->getStore();
$storeConfig = current($this->storeConfigManager->getStoreConfigs([$store->getCode()]));
$storeConfigData = [
@@ -78,4 +99,23 @@ public function getStoreConfig() : array
];
return $storeConfigData;
}
+
+ /**
+ * Get extended config data
+ *
+ * @return array
+ */
+ private function getExtendedConfigData()
+ {
+ $store = $this->storeManager->getStore();
+ $extendedConfigData = [];
+ foreach ($this->extendedConfigData as $key => $path) {
+ $extendedConfigData[$key] = $this->scopeConfig->getValue(
+ $path,
+ ScopeInterface::SCOPE_STORE,
+ $store->getId()
+ );
+ }
+ return $extendedConfigData;
+ }
}
diff --git a/app/code/Magento/StoreGraphQl/Model/Resolver/StoreConfigResolver.php b/app/code/Magento/StoreGraphQl/Model/Resolver/StoreConfigResolver.php
index 39fcd1bf279..9c426172de8 100644
--- a/app/code/Magento/StoreGraphQl/Model/Resolver/StoreConfigResolver.php
+++ b/app/code/Magento/StoreGraphQl/Model/Resolver/StoreConfigResolver.php
@@ -23,12 +23,12 @@ class StoreConfigResolver implements ResolverInterface
private $storeConfigDataProvider;
/**
- * @param StoreConfigDataProvider $storeConfigDataProvider
+ * @param StoreConfigDataProvider $storeConfigsDataProvider
*/
public function __construct(
- StoreConfigDataProvider $storeConfigDataProvider
+ StoreConfigDataProvider $storeConfigsDataProvider
) {
- $this->storeConfigDataProvider = $storeConfigDataProvider;
+ $this->storeConfigDataProvider = $storeConfigsDataProvider;
}
/**
@@ -41,8 +41,6 @@ public function resolve(
array $value = null,
array $args = null
) {
-
- $storeConfigData = $this->storeConfigDataProvider->getStoreConfig();
- return $storeConfigData;
+ return $this->storeConfigDataProvider->getStoreConfigData();
}
}
diff --git a/app/code/Magento/StoreGraphQl/composer.json b/app/code/Magento/StoreGraphQl/composer.json
index d03d759babd..d53ba9fbb00 100644
--- a/app/code/Magento/StoreGraphQl/composer.json
+++ b/app/code/Magento/StoreGraphQl/composer.json
@@ -8,8 +8,7 @@
"magento/module-store": "*"
},
"suggest": {
- "magento/module-graph-ql": "*",
- "magento/module-catalog-graph-ql": "*"
+ "magento/module-graph-ql": "*"
},
"license": [
"OSL-3.0",
diff --git a/app/code/Magento/Swatches/Controller/Ajax/Media.php b/app/code/Magento/Swatches/Controller/Ajax/Media.php
index 079ba8f8971..7692245e9b2 100644
--- a/app/code/Magento/Swatches/Controller/Ajax/Media.php
+++ b/app/code/Magento/Swatches/Controller/Ajax/Media.php
@@ -12,7 +12,7 @@
/**
* Class Media
*/
-class Media extends \Magento\Framework\App\Action\Action
+class Media extends \Magento\Framework\App\Action\Action implements \Magento\Framework\App\Action\HttpGetActionInterface
{
/**
* @var \Magento\Catalog\Model\Product Factory
@@ -24,18 +24,26 @@ class Media extends \Magento\Framework\App\Action\Action
*/
private $swatchHelper;
+ /**
+ * @var \Magento\PageCache\Model\Config
+ */
+ protected $config;
+
/**
* @param Context $context
* @param \Magento\Catalog\Model\ProductFactory $productModelFactory
* @param \Magento\Swatches\Helper\Data $swatchHelper
+ * @param \Magento\PageCache\Model\Config $config
*/
public function __construct(
Context $context,
\Magento\Catalog\Model\ProductFactory $productModelFactory,
- \Magento\Swatches\Helper\Data $swatchHelper
+ \Magento\Swatches\Helper\Data $swatchHelper,
+ \Magento\PageCache\Model\Config $config
) {
$this->productModelFactory = $productModelFactory;
$this->swatchHelper = $swatchHelper;
+ $this->config = $config;
parent::__construct($context);
}
@@ -48,14 +56,23 @@ public function __construct(
public function execute()
{
$productMedia = [];
+
+ /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+ $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
+
+ /** @var \Magento\Framework\App\ResponseInterface $response */
+ $response = $this->getResponse();
+
if ($productId = (int)$this->getRequest()->getParam('product_id')) {
+ $product = $this->productModelFactory->create()->load($productId);
$productMedia = $this->swatchHelper->getProductMediaGallery(
- $this->productModelFactory->create()->load($productId)
+ $product
);
+ $resultJson->setHeader('X-Magento-Tags', implode(',', $product->getIdentities()));
+
+ $response->setPublicHeaders($this->config->getTtl());
}
- /** @var \Magento\Framework\Controller\Result\Json $resultJson */
- $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
$resultJson->setData($productMedia);
return $resultJson;
}
diff --git a/app/code/Magento/Swatches/Test/Unit/Controller/Ajax/MediaTest.php b/app/code/Magento/Swatches/Test/Unit/Controller/Ajax/MediaTest.php
index 7a110c63da7..5a11e2787bc 100644
--- a/app/code/Magento/Swatches/Test/Unit/Controller/Ajax/MediaTest.php
+++ b/app/code/Magento/Swatches/Test/Unit/Controller/Ajax/MediaTest.php
@@ -20,6 +20,9 @@ class MediaTest extends \PHPUnit\Framework\TestCase
/** @var \Magento\Catalog\Model\ProductFactory|\PHPUnit_Framework_MockObject_MockObject */
private $productModelFactoryMock;
+ /** @var \Magento\PageCache\Model\Config|\PHPUnit_Framework_MockObject_MockObject */
+ private $config;
+
/** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */
private $productMock;
@@ -29,6 +32,9 @@ class MediaTest extends \PHPUnit\Framework\TestCase
/** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */
private $requestMock;
+ /** @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject */
+ private $responseMock;
+
/** @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject */
private $resultFactory;
@@ -57,11 +63,20 @@ protected function setUp()
\Magento\Catalog\Model\ProductFactory::class,
['create']
);
+ $this->config = $this->createMock(\Magento\PageCache\Model\Config::class);
+ $this->config->method('getTtl')->willReturn(1);
+
$this->productMock = $this->createMock(\Magento\Catalog\Model\Product::class);
$this->contextMock = $this->createMock(\Magento\Framework\App\Action\Context::class);
$this->requestMock = $this->createMock(\Magento\Framework\App\RequestInterface::class);
$this->contextMock->method('getRequest')->willReturn($this->requestMock);
+ $this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['setPublicHeaders'])
+ ->getMockForAbstractClass();
+ $this->responseMock->method('setPublicHeaders')->willReturnSelf();
+ $this->contextMock->method('getResponse')->willReturn($this->responseMock);
$this->resultFactory = $this->createPartialMock(\Magento\Framework\Controller\ResultFactory::class, ['create']);
$this->contextMock->method('getResultFactory')->willReturn($this->resultFactory);
@@ -73,7 +88,8 @@ protected function setUp()
[
'context' => $this->contextMock,
'swatchHelper' => $this->swatchHelperMock,
- 'productModelFactory' => $this->productModelFactoryMock
+ 'productModelFactory' => $this->productModelFactoryMock,
+ 'config' => $this->config
]
);
}
@@ -86,6 +102,10 @@ public function testExecute()
->method('load')
->with(59)
->willReturn($this->productMock);
+ $this->productMock
+ ->expects($this->once())
+ ->method('getIdentities')
+ ->willReturn(['tags']);
$this->productModelFactoryMock
->expects($this->once())
diff --git a/app/code/Magento/Swatches/composer.json b/app/code/Magento/Swatches/composer.json
index 0940003b6a7..09d3e05008a 100644
--- a/app/code/Magento/Swatches/composer.json
+++ b/app/code/Magento/Swatches/composer.json
@@ -13,6 +13,7 @@
"magento/module-configurable-product": "*",
"magento/module-customer": "*",
"magento/module-eav": "*",
+ "magento/module-page-cache": "*",
"magento/module-media-storage": "*",
"magento/module-store": "*",
"magento/module-theme": "*"
diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js
index 01411523108..46083cd9fb4 100644
--- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js
+++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js
@@ -45,7 +45,7 @@ define([
get tabsFront() {
return this.attrTabsFront.length ? this.attrTabsFront.closest('li') : $('#front_fieldset-wrapper');
},
- selectFields: ['select', 'multiselect', 'price', 'swatch_text', 'swatch_visual'],
+ selectFields: ['boolean', 'select', 'multiselect', 'price', 'swatch_text', 'swatch_visual'],
/**
* @this {swatchProductAttributes}
diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
index 853eba3c98d..63dbd31751e 100644
--- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
+++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js
@@ -1029,12 +1029,14 @@ define([
mediaCallData.isAjax = true;
$widget._XhrKiller();
$widget._EnableProductMediaLoader($this);
- $widget.xhr = $.get(
- $widget.options.mediaCallback,
- mediaCallData,
- mediaSuccessCallback,
- 'json'
- ).done(function () {
+ $widget.xhr = $.ajax({
+ url: $widget.options.mediaCallback,
+ cache: true,
+ type: 'GET',
+ dataType: 'json',
+ data: mediaCallData,
+ success: mediaSuccessCallback
+ }).done(function () {
$widget._XhrKiller();
});
}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php
index b91eef7b6f7..565af0e0bf9 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Tax\Controller\Adminhtml\Rate;
-class Index extends \Magento\Tax\Controller\Adminhtml\Rate
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\Tax\Controller\Adminhtml\Rate implements HttpGetActionInterface
{
/**
* Show Main Grid
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php
index 71b6d7bf393..1e46f0ea3d2 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Tax\Controller\Adminhtml\Rule;
+use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\Controller\ResultFactory;
-class Delete extends \Magento\Tax\Controller\Adminhtml\Rule
+class Delete extends \Magento\Tax\Controller\Adminhtml\Rule implements HttpPostActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Redirect
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Edit.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Edit.php
index dc0f5188025..740d7e8afe6 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Edit.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Edit.php
@@ -6,9 +6,10 @@
*/
namespace Magento\Tax\Controller\Adminhtml\Rule;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Framework\Controller\ResultFactory;
-class Edit extends \Magento\Tax\Controller\Adminhtml\Rule
+class Edit extends \Magento\Tax\Controller\Adminhtml\Rule implements HttpGetActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Page|\Magento\Backend\Model\View\Result\Redirect
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php
index ddf6099a4f8..fd774777e3e 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Tax\Controller\Adminhtml\Rule;
-class Index extends \Magento\Tax\Controller\Adminhtml\Rule
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\Tax\Controller\Adminhtml\Rule implements HttpGetActionInterface
{
/**
* @return \Magento\Backend\Model\View\Result\Page
diff --git a/app/code/Magento/Tax/Model/ResourceModel/Report/Tax/Createdat.php b/app/code/Magento/Tax/Model/ResourceModel/Report/Tax/Createdat.php
index ebf699db552..60cb6fe2898 100644
--- a/app/code/Magento/Tax/Model/ResourceModel/Report/Tax/Createdat.php
+++ b/app/code/Magento/Tax/Model/ResourceModel/Report/Tax/Createdat.php
@@ -11,6 +11,9 @@
*/
namespace Magento\Tax\Model\ResourceModel\Report\Tax;
+/**
+ * Class for tax report resource model with aggregation by created at
+ */
class Createdat extends \Magento\Reports\Model\ResourceModel\Report\AbstractReport
{
/**
@@ -84,7 +87,7 @@ protected function _aggregateByOrder($aggregationField, $from, $to)
'order_status' => 'e.status',
'percent' => 'MAX(tax.' . $connection->quoteIdentifier('percent') . ')',
'orders_count' => 'COUNT(DISTINCT e.entity_id)',
- 'tax_base_amount_sum' => 'SUM(tax.base_amount * e.base_to_global_rate)',
+ 'tax_base_amount_sum' => 'SUM(tax.base_real_amount * e.base_to_global_rate)',
];
$select = $connection->select()->from(
diff --git a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml
index d6e5f4b693c..aaea515aa90 100644
--- a/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml
+++ b/app/code/Magento/Tax/Test/Mftf/ActionGroup/AdminTaxActionGroup.xml
@@ -16,14 +16,18 @@
+
+
+
+
@@ -33,7 +37,9 @@
+
+
@@ -54,13 +60,17 @@
+
+
+
+
@@ -69,7 +79,9 @@
+
+
@@ -103,4 +115,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Data/TaxCodeData.xml b/app/code/Magento/Tax/Test/Mftf/Data/TaxCodeData.xml
index 42fd0135737..36929ef2e3f 100644
--- a/app/code/Magento/Tax/Test/Mftf/Data/TaxCodeData.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Data/TaxCodeData.xml
@@ -26,4 +26,16 @@
*
0
+
+ Texas
+ United States
+ 78729
+ 7.25
+
+
+ Texas
+ United States
+ 78729
+ 0.125
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxReportsSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxReportsSection.xml
new file mode 100644
index 00000000000..80101687e17
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxReportsSection.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml
index 9727c649d7e..6c258f2de18 100644
--- a/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Section/AdminTaxRulesSection.xml
@@ -19,5 +19,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml
new file mode 100644
index 00000000000..68fe8087c4f
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Mftf/Test/AdminTaxReportGridTest.xml
@@ -0,0 +1,222 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $0.15
+ amountOfFirstTaxRate
+
+
+
+ $8.92
+ amountOfSecondTaxRate
+
+
+
+ $9.07
+ amountOfSubtotalTaxRate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml
index 47161001219..9bc44dec0b5 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestPhysicalQuoteTest.xml
@@ -16,10 +16,11 @@
-
-
+
+
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestVirtualQuoteTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestVirtualQuoteTest.xml
index 88496b8e2cd..06f6abb2973 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestVirtualQuoteTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxInformationInShoppingCartForGuestVirtualQuoteTest.xml
@@ -16,8 +16,6 @@
-
-
diff --git a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportExport.php b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportExport.php
index 929c9db01a2..4264f5c3b77 100644
--- a/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportExport.php
+++ b/app/code/Magento/TaxImportExport/Controller/Adminhtml/Rate/ImportExport.php
@@ -5,9 +5,10 @@
*/
namespace Magento\TaxImportExport\Controller\Adminhtml\Rate;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Framework\Controller\ResultFactory;
-class ImportExport extends \Magento\TaxImportExport\Controller\Adminhtml\Rate
+class ImportExport extends \Magento\TaxImportExport\Controller\Adminhtml\Rate implements HttpGetActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Index.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Index.php
index d51fd658075..1a136cca4d6 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Index.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Index.php
@@ -6,11 +6,13 @@
*/
namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
/**
* Class Index
* @deprecated 100.2.0
*/
-class Index extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+class Index extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme implements HttpGetActionInterface
{
/**
* Index action
diff --git a/app/code/Magento/Theme/Model/Wysiwyg/Storage.php b/app/code/Magento/Theme/Model/Wysiwyg/Storage.php
index 82206b8eb1c..2c3350e695a 100644
--- a/app/code/Magento/Theme/Model/Wysiwyg/Storage.php
+++ b/app/code/Magento/Theme/Model/Wysiwyg/Storage.php
@@ -11,6 +11,11 @@
use Magento\Framework\App\Filesystem\DirectoryList;
+/**
+ * Class Storage
+ *
+ * @package Magento\Theme\Model\Wysiwyg
+ */
class Storage
{
/**
@@ -127,14 +132,6 @@ public function uploadFile($targetPath)
$this->_createThumbnail($targetPath . '/' . $uploader->getUploadedFileName());
- $result['cookie'] = [
- 'name' => $this->_helper->getSession()->getName(),
- 'value' => $this->_helper->getSession()->getSessionId(),
- 'lifetime' => $this->_helper->getSession()->getCookieLifetime(),
- 'path' => $this->_helper->getSession()->getCookiePath(),
- 'domain' => $this->_helper->getSession()->getCookieDomain()
- ];
-
return $result;
}
diff --git a/app/code/Magento/Theme/Test/Unit/Model/Wysiwyg/StorageTest.php b/app/code/Magento/Theme/Test/Unit/Model/Wysiwyg/StorageTest.php
index 0951f7b50f2..ddd6ebc43ce 100644
--- a/app/code/Magento/Theme/Test/Unit/Model/Wysiwyg/StorageTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Model/Wysiwyg/StorageTest.php
@@ -152,8 +152,7 @@ public function testUploadFile()
$this->_helperStorage->expects($this->any())->method('getSession')->will($this->returnValue($session));
$expectedResult = [
- 'not_empty',
- 'cookie' => ['name' => null, 'value' => null, 'lifetime' => null, 'path' => null, 'domain' => null],
+ 'not_empty'
];
$this->assertEquals($expectedResult, $this->_storageModel->uploadFile($this->_storageRoot));
diff --git a/app/code/Magento/Theme/etc/config.xml b/app/code/Magento/Theme/etc/config.xml
index a6984b449d9..b44691c0df9 100644
--- a/app/code/Magento/Theme/etc/config.xml
+++ b/app/code/Magento/Theme/etc/config.xml
@@ -46,6 +46,7 @@ Disallow: /*SID=
diff --git a/app/code/Magento/Theme/etc/di.xml b/app/code/Magento/Theme/etc/di.xml
index 5ff82ce2db6..148267feeaa 100644
--- a/app/code/Magento/Theme/etc/di.xml
+++ b/app/code/Magento/Theme/etc/di.xml
@@ -214,6 +214,10 @@
- design/footer/absolute_footer
- other_settings/footer
+ -
+
- design/footer/report_bugs
+ - other_settings/footer
+
-
- design/search_engine_robots/default_robots
- other_settings/search_engine_robots
diff --git a/app/code/Magento/Theme/i18n/en_US.csv b/app/code/Magento/Theme/i18n/en_US.csv
index db641b5da1f..c8c586f0bc6 100644
--- a/app/code/Magento/Theme/i18n/en_US.csv
+++ b/app/code/Magento/Theme/i18n/en_US.csv
@@ -188,3 +188,4 @@ Settings,Settings
ID,ID
View,View
Action,Action
+"Display Report Bugs Link","Display Report Bugs Link"
diff --git a/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml b/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml
index 48adca3b1a1..8d4580f90c7 100644
--- a/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml
+++ b/app/code/Magento/Theme/view/adminhtml/ui_component/design_config_form.xml
@@ -233,6 +233,20 @@
footer_copyright
+
+
+ text
+
+ footer_report_bugs
+
+
+
+
+
-
+
diff --git a/app/code/Magento/ThemeGraphQl/README.md b/app/code/Magento/ThemeGraphQl/README.md
new file mode 100644
index 00000000000..fed6b54fa5c
--- /dev/null
+++ b/app/code/Magento/ThemeGraphQl/README.md
@@ -0,0 +1,4 @@
+# ThemeGraphQlhQl
+
+**ThemeGraphQlhQl** provides type information for the GraphQl module
+to generate theme fields information endpoints.
diff --git a/app/code/Magento/ThemeGraphQl/composer.json b/app/code/Magento/ThemeGraphQl/composer.json
new file mode 100644
index 00000000000..e3aac55aea3
--- /dev/null
+++ b/app/code/Magento/ThemeGraphQl/composer.json
@@ -0,0 +1,24 @@
+{
+ "name": "magento/module-theme-graph-ql",
+ "description": "N/A",
+ "type": "magento2-module",
+ "require": {
+ "php": "~7.1.3||~7.2.0",
+ "magento/framework": "*"
+ },
+ "suggest": {
+ "magento/module-store-graph-ql": "*"
+ },
+ "license": [
+ "OSL-3.0",
+ "AFL-3.0"
+ ],
+ "autoload": {
+ "files": [
+ "registration.php"
+ ],
+ "psr-4": {
+ "Magento\\ThemeGraphQl\\": ""
+ }
+ }
+}
diff --git a/app/code/Magento/ThemeGraphQl/etc/module.xml b/app/code/Magento/ThemeGraphQl/etc/module.xml
new file mode 100644
index 00000000000..0e10b776af9
--- /dev/null
+++ b/app/code/Magento/ThemeGraphQl/etc/module.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/app/code/Magento/ThemeGraphQl/etc/schema.graphqls b/app/code/Magento/ThemeGraphQl/etc/schema.graphqls
new file mode 100644
index 00000000000..325fcc8bd98
--- /dev/null
+++ b/app/code/Magento/ThemeGraphQl/etc/schema.graphqls
@@ -0,0 +1,19 @@
+# Copyright © Magento, Inc. All rights reserved.
+# See COPYING.txt for license details.
+type StoreConfig @doc(description: "The type contains information about a store config") {
+ head_shortcut_icon : String @doc(description: "Favicon Icon")
+ default_title : String @doc(description: "Default Page Title")
+ title_prefix : String @doc(description: "Page Title Prefix")
+ title_suffix : String @doc(description: "Page Title Suffix")
+ default_description : String @doc(description: "Default Meta Description")
+ default_keywords : String @doc(description: "Default Meta Keywords")
+ head_includes : String @doc(description: "Scripts and Style Sheets")
+ demonotice : Int @doc(description: "Display Demo Store Notice")
+ header_logo_src : String @doc(description: "Logo Image")
+ logo_width : Int @doc(description: "Logo Attribute Width")
+ logo_height : Int @doc(description: "Logo Attribute Height")
+ welcome : String @doc(description: "Welcome Text")
+ logo_alt : String @doc(description: "Logo Image Alt")
+ absolute_footer : String @doc(description: "Footer Miscellaneous HTML")
+ copyright : String @doc(description: "Copyright")
+}
diff --git a/app/code/Magento/ThemeGraphQl/registration.php b/app/code/Magento/ThemeGraphQl/registration.php
new file mode 100644
index 00000000000..e320fbc9868
--- /dev/null
+++ b/app/code/Magento/ThemeGraphQl/registration.php
@@ -0,0 +1,10 @@
+getSortOrder($a);
- $b['sortOrder'] = $this->getSortOrder($b);
-
- if ($a['sortOrder'] == $b['sortOrder']) {
- return 0;
- }
-
- return ($a['sortOrder'] < $b['sortOrder']) ? -1 : 1;
+ return $this->getSortOrder($a) <=> $this->getSortOrder($b);
});
return $data;
diff --git a/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js b/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js
index fe312738469..ac1de4631e9 100644
--- a/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js
+++ b/app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js
@@ -224,7 +224,7 @@ define([
*/
build: function (parent, node, name) {
var defaults = parent && parent.childDefaults || {},
- children = node.children,
+ children = this.filterDisabledChildren(node.children),
type = getNodeType(parent, node),
dataScope = getDataScope(parent, node),
component,
@@ -294,6 +294,35 @@ define([
return node;
},
+ /**
+ * Filter out all disabled components.
+ *
+ * @param {Object} children
+ * @returns {*}
+ */
+ filterDisabledChildren: function (children) {
+ var cIds;
+
+ //cleanup children config.componentDisabled = true
+ if (children && typeof children === 'object') {
+ cIds = Object.keys(children);
+
+ if (cIds) {
+ _.each(cIds, function (cId) {
+ if (typeof children[cId] === 'object' &&
+ children[cId].hasOwnProperty('config') &&
+ typeof children[cId].config === 'object' &&
+ children[cId].config.hasOwnProperty('componentDisabled') &&
+ children[cId].config.componentDisabled === true) {
+ delete children[cId];
+ }
+ });
+ }
+ }
+
+ return children;
+ },
+
/**
* Init component.
*
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js
index be7a1a13fbd..c75f7797cf0 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js
@@ -11,8 +11,9 @@ define([
'mageUtils',
'uiRegistry',
'./column',
- 'Magento_Ui/js/modal/confirm'
-], function (_, utils, registry, Column, confirm) {
+ 'Magento_Ui/js/modal/confirm',
+ 'mage/dataPost'
+], function (_, utils, registry, Column, confirm, dataPost) {
'use strict';
return Column.extend({
@@ -267,7 +268,14 @@ define([
* @param {Object} action - Action's data.
*/
defaultCallback: function (actionIndex, recordId, action) {
- window.location.href = action.href;
+ if (action.post) {
+ dataPost().postData({
+ action: action.href,
+ data: {}
+ });
+ } else {
+ window.location.href = action.href;
+ }
},
/**
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js b/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js
index 4590af4f2d6..03012918f4a 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/view/utils/dom-observer.js
@@ -12,7 +12,8 @@ define([
var counter = 1,
watchers,
- globalObserver;
+ globalObserver,
+ disabledNodes = [];
watchers = {
selectors: {},
@@ -238,11 +239,58 @@ define([
};
}
+ /**
+ * Verify if the DOM node is a child of a defined disabled node, if so we shouldn't observe provided mutation.
+ *
+ * @param {Object} mutation - a single mutation
+ * @returns {Boolean}
+ */
+ function shouldObserveMutation(mutation) {
+ var isDisabled;
+
+ if (disabledNodes.length > 0) {
+ // Iterate through the disabled nodes and determine if this mutation is occurring inside one of them
+ isDisabled = _.find(disabledNodes, function (node) {
+ return node === mutation.target || $.contains(node, mutation.target);
+ });
+
+ // If we find a matching node we should not observe the mutation
+ return !isDisabled;
+ }
+
+ return true;
+ }
+
+ /**
+ * Should we observe these mutations? Check the first and last mutation to determine if this is a disabled mutation,
+ * we check both the first and last in case one has been removed from the DOM during the process of the mutation.
+ *
+ * @param {Array} mutations - An array of mutation records.
+ * @returns {Boolean}
+ */
+ function shouldObserveMutations(mutations) {
+ var firstMutation,
+ lastMutation;
+
+ if (mutations.length > 0) {
+ firstMutation = mutations[0];
+ lastMutation = mutations[mutations.length - 1];
+
+ return shouldObserveMutation(firstMutation) && shouldObserveMutation(lastMutation);
+ }
+
+ return true;
+ }
+
globalObserver = new MutationObserver(function (mutations) {
- var changes = formChangesLists(mutations);
+ var changes;
+
+ if (shouldObserveMutations(mutations)) {
+ changes = formChangesLists(mutations);
- changes.removed.forEach(processRemoved);
- changes.added.forEach(processAdded);
+ changes.removed.forEach(processRemoved);
+ changes.added.forEach(processAdded);
+ }
});
globalObserver.observe(document.body, {
@@ -251,6 +299,16 @@ define([
});
return {
+ /**
+ * Disable a node from being observed by the mutations, you may want to disable specific aspects of the
+ * application which are heavy on DOM changes. The observer running on some actions could cause significant
+ * delays and degrade the performance of that specific part of the application exponentially.
+ *
+ * @param {HTMLElement} node - a HTML node within the document
+ */
+ disableNode: function (node) {
+ disabledNodes.push(node);
+ },
/**
* Adds listener for the appearance of nodes that matches provided
diff --git a/app/code/Magento/Ui/view/base/web/js/modal/modal.js b/app/code/Magento/Ui/view/base/web/js/modal/modal.js
index f016b0dbefd..c81274337f4 100644
--- a/app/code/Magento/Ui/view/base/web/js/modal/modal.js
+++ b/app/code/Magento/Ui/view/base/web/js/modal/modal.js
@@ -363,14 +363,7 @@ define([
this.modal.data('active', false);
if (this.overlay) {
- // In cases when one modal is closed but there is another modal open (e.g. admin notifications)
- // to avoid collisions between overlay and modal zIndexes
- // overlay zIndex is set to be less than modal one
- if (this._getVisibleCount() === 1) {
- this.overlay.zIndex(this.prevOverlayIndex - 1);
- } else {
- this.overlay.zIndex(this.prevOverlayIndex);
- }
+ this.overlay.zIndex(this.prevOverlayIndex - 1);
}
},
diff --git a/app/code/Magento/UrlRewrite/Block/Edit.php b/app/code/Magento/UrlRewrite/Block/Edit.php
index 115c5db43a7..c8716f6c80f 100644
--- a/app/code/Magento/UrlRewrite/Block/Edit.php
+++ b/app/code/Magento/UrlRewrite/Block/Edit.php
@@ -173,7 +173,7 @@ protected function _addDeleteButton()
['id' => $this->getUrlRewrite()->getId()]
)
)
- . ')',
+ . ', {data: {}})',
'class' => 'scalable delete',
'level' => -1
]
@@ -243,7 +243,7 @@ private function _getSelectorBlock()
* Since buttons are set as children, we remove them as children after generating them
* not to duplicate them in future
*
- * @param string $area
+ * @param string|null $area
* @return string
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
diff --git a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/CmsPageGrid.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/CmsPageGrid.php
index 480efa82357..7240dfc36f1 100644
--- a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/CmsPageGrid.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/CmsPageGrid.php
@@ -6,7 +6,11 @@
*/
namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
-class CmsPageGrid extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
+use Magento\Framework\App\Action\HttpGetActionInterface;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
+use Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite as RewriteAction;
+
+class CmsPageGrid extends RewriteAction implements HttpPostActionInterface, HttpGetActionInterface
{
/**
* Ajax CMS pages grid action
diff --git a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Delete.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Delete.php
index f8f7b145e28..dc49776a1ac 100644
--- a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Delete.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Delete.php
@@ -6,7 +6,9 @@
*/
namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
-class Delete extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
+use Magento\Framework\App\Action\HttpPostActionInterface;
+
+class Delete extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite implements HttpPostActionInterface
{
/**
* URL rewrite delete action
diff --git a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Edit.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Edit.php
index b7ff9221300..e2161f4ffd9 100644
--- a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Edit.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Edit.php
@@ -6,7 +6,9 @@
*/
namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
-class Edit extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Edit extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite implements HttpGetActionInterface
{
/**#@+
* Modes
diff --git a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Index.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Index.php
index 066377ff7bd..4f3a1e7849e 100644
--- a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Index.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
-class Index extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite implements HttpGetActionInterface
{
/**
* Show URL rewrites index page
diff --git a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Save.php b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Save.php
index 6325fe162d9..c508e85d87c 100644
--- a/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Save.php
+++ b/app/code/Magento/UrlRewrite/Controller/Adminhtml/Url/Rewrite/Save.php
@@ -7,11 +7,12 @@
namespace Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
-class Save extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite
+class Save extends \Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite implements HttpPostActionInterface
{
/**
* @var \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator
diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php
new file mode 100644
index 00000000000..1c25ffd1e9f
--- /dev/null
+++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php
@@ -0,0 +1,148 @@
+urlFinder = $urlFinder;
+ $this->storeManager = $storeManager;
+ $this->customUrlLocator = $customUrlLocator;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function resolve(
+ Field $field,
+ $context,
+ ResolveInfo $info,
+ array $value = null,
+ array $args = null
+ ) {
+ if (!isset($args['url']) || empty(trim($args['url']))) {
+ throw new GraphQlInputException(__('"url" argument should be specified and not empty'));
+ }
+
+ $result = null;
+ $url = $args['url'];
+ if (substr($url, 0, 1) === '/' && $url !== '/') {
+ $url = ltrim($url, '/');
+ }
+ $customUrl = $this->customUrlLocator->locateUrl($url);
+ $url = $customUrl ?: $url;
+ $urlRewrite = $this->findCanonicalUrl($url);
+ if ($urlRewrite) {
+ $result = [
+ 'id' => $urlRewrite->getEntityId(),
+ 'canonical_url' => $urlRewrite->getTargetPath(),
+ 'type' => $this->sanitizeType($urlRewrite->getEntityType())
+ ];
+ }
+ return $result;
+ }
+
+ /**
+ * Find the canonical url passing through all redirects if any
+ *
+ * @param string $requestPath
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
+ */
+ private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
+ {
+ $urlRewrite = $this->findUrlFromRequestPath($requestPath);
+ if ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
+ while ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
+ $urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath());
+ }
+ }
+ if (!$urlRewrite) {
+ $urlRewrite = $this->findUrlFromTargetPath($requestPath);
+ }
+
+ return $urlRewrite;
+ }
+
+ /**
+ * Find a url from a request url on the current store
+ *
+ * @param string $requestPath
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
+ */
+ private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
+ {
+ return $this->urlFinder->findOneByData(
+ [
+ 'request_path' => $requestPath,
+ 'store_id' => $this->storeManager->getStore()->getId()
+ ]
+ );
+ }
+
+ /**
+ * Find a url from a target url on the current store
+ *
+ * @param string $targetPath
+ * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
+ */
+ private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
+ {
+ return $this->urlFinder->findOneByData(
+ [
+ 'target_path' => $targetPath,
+ 'store_id' => $this->storeManager->getStore()->getId()
+ ]
+ );
+ }
+
+ /**
+ * Sanitize the type to fit schema specifications
+ *
+ * @param string $type
+ * @return string
+ */
+ private function sanitizeType(string $type) : string
+ {
+ return strtoupper(str_replace('-', '_', $type));
+ }
+}
diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php
index 488f1281ce3..0c4c78b5829 100644
--- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php
+++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php
@@ -11,12 +11,12 @@
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
-use Magento\Store\Model\StoreManagerInterface;
+use Magento\Framework\Model\AbstractModel;
use Magento\UrlRewrite\Model\UrlFinderInterface;
-use Magento\UrlRewriteGraphQl\Model\Resolver\UrlRewrite\CustomUrlLocatorInterface;
+use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteDTO;
/**
- * UrlRewrite field resolver, used for GraphQL request processing.
+ * Returns URL rewrites list for the specified product
*/
class UrlRewrite implements ResolverInterface
{
@@ -25,29 +25,13 @@ class UrlRewrite implements ResolverInterface
*/
private $urlFinder;
- /**
- * @var StoreManagerInterface
- */
- private $storeManager;
-
- /**
- * @var CustomUrlLocatorInterface
- */
- private $customUrlLocator;
-
/**
* @param UrlFinderInterface $urlFinder
- * @param StoreManagerInterface $storeManager
- * @param CustomUrlLocatorInterface $customUrlLocator
*/
public function __construct(
- UrlFinderInterface $urlFinder,
- StoreManagerInterface $storeManager,
- CustomUrlLocatorInterface $customUrlLocator
+ UrlFinderInterface $urlFinder
) {
$this->urlFinder = $urlFinder;
- $this->storeManager = $storeManager;
- $this->customUrlLocator = $customUrlLocator;
}
/**
@@ -59,90 +43,51 @@ public function resolve(
ResolveInfo $info,
array $value = null,
array $args = null
- ) {
- if (!isset($args['url']) || empty(trim($args['url']))) {
- throw new GraphQlInputException(__('"url" argument should be specified and not empty'));
+ ): array {
+ if (!isset($value['model'])) {
+ throw new GraphQlInputException(__('"model" value should be specified'));
}
- $result = null;
- $url = $args['url'];
- if (substr($url, 0, 1) === '/' && $url !== '/') {
- $url = ltrim($url, '/');
- }
- $customUrl = $this->customUrlLocator->locateUrl($url);
- $url = $customUrl ?: $url;
- $urlRewrite = $this->findCanonicalUrl($url);
- if ($urlRewrite) {
- $result = [
- 'id' => $urlRewrite->getEntityId(),
- 'canonical_url' => $urlRewrite->getTargetPath(),
- 'type' => $this->sanitizeType($urlRewrite->getEntityType())
- ];
- }
- return $result;
- }
+ /** @var AbstractModel $entity */
+ $entity = $value['model'];
+ $entityId = $entity->getEntityId();
- /**
- * Find the canonical url passing through all redirects if any
- *
- * @param string $requestPath
- * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
- */
- private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
- {
- $urlRewrite = $this->findUrlFromRequestPath($requestPath);
- if ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
- while ($urlRewrite && $urlRewrite->getRedirectType() > 0) {
- $urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath());
+ $urlRewriteCollection = $this->urlFinder->findAllByData([UrlRewriteDTO::ENTITY_ID => $entityId]);
+ $urlRewrites = [];
+
+ /** @var UrlRewriteDTO $urlRewrite */
+ foreach ($urlRewriteCollection as $urlRewrite) {
+ if ($urlRewrite->getRedirectType() !== 0) {
+ continue;
}
+
+ $urlRewrites[] = [
+ 'url' => $urlRewrite->getRequestPath(),
+ 'parameters' => $this->getUrlParameters($urlRewrite->getTargetPath())
+ ];
}
- if (!$urlRewrite) {
- $urlRewrite = $this->findUrlFromTargetPath($requestPath);
- }
-
- return $urlRewrite;
- }
- /**
- * Find a url from a request url on the current store
- *
- * @param string $requestPath
- * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
- */
- private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
- {
- return $this->urlFinder->findOneByData(
- [
- 'request_path' => $requestPath,
- 'store_id' => $this->storeManager->getStore()->getId()
- ]
- );
+ return $urlRewrites;
}
/**
- * Find a url from a target url on the current store
+ * Parses target path and extracts parameters
*
* @param string $targetPath
- * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
+ * @return array
*/
- private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite
+ private function getUrlParameters(string $targetPath): array
{
- return $this->urlFinder->findOneByData(
- [
- 'target_path' => $targetPath,
- 'store_id' => $this->storeManager->getStore()->getId()
- ]
- );
- }
+ $urlParameters = [];
+ $targetPathParts = explode('/', trim($targetPath, '/'));
- /**
- * Sanitize the type to fit schema specifications
- *
- * @param string $type
- * @return string
- */
- private function sanitizeType(string $type) : string
- {
- return strtoupper(str_replace('-', '_', $type));
+ for ($i = 3; ($i < sizeof($targetPathParts) - 1); $i += 2) {
+ $urlParameters[] = [
+ 'name' => $targetPathParts[$i],
+ 'value' => $targetPathParts[$i + 1]
+ ];
+ }
+
+ return $urlParameters;
}
}
diff --git a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls
index 38f1d9c6563..dae695c69a3 100644
--- a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls
+++ b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls
@@ -8,8 +8,18 @@ type EntityUrl @doc(description: "EntityUrl is an output object containing the `
}
type Query {
- urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite") @doc(description: "The urlResolver query returns the canonical URL for a specified product, category or CMS page")
+ urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\EntityUrl") @doc(description: "The urlResolver query returns the relative URL for a specified product, category or CMS page")
}
enum UrlRewriteEntityTypeEnum {
}
+
+type UrlRewrite @doc(description: "The object contains URL rewrite details") {
+ url: String @doc(description: "Request URL")
+ parameters: [HttpQueryParameter] @doc(description: "Request parameters")
+}
+
+type HttpQueryParameter @doc(description: "The object details of target path parameters") {
+ name: String @doc(description: "Parameter name")
+ value: String @doc(description: "Parameter value")
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php b/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php
index c0e78fae2c2..565b312325d 100644
--- a/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php
+++ b/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php
@@ -6,8 +6,10 @@
*/
namespace Magento\User\Controller\Adminhtml\Auth;
-use Magento\Security\Model\SecurityManager;
+use Magento\Framework\App\Action\HttpGetActionInterface;
+use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\ObjectManager;
+use Magento\Security\Model\SecurityManager;
use Magento\Backend\App\Action\Context;
use Magento\User\Model\UserFactory;
use Magento\User\Model\ResourceModel\User\CollectionFactory;
@@ -16,14 +18,25 @@
use Magento\Framework\Exception\SecurityViolationException;
use Magento\User\Controller\Adminhtml\Auth;
use Magento\Backend\Helper\Data;
+use Magento\User\Model\Spi\NotificatorInterface;
-class Forgotpassword extends Auth
+/**
+ * Initiate forgot-password process.
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class Forgotpassword extends Auth implements HttpGetActionInterface, HttpPostActionInterface
{
/**
* @var SecurityManager
*/
protected $securityManager;
+ /**
+ * @var NotificatorInterface
+ */
+ private $notificator;
+
/**
* User model factory
*
@@ -41,13 +54,16 @@ class Forgotpassword extends Auth
* @param UserFactory $userFactory
* @param SecurityManager $securityManager
* @param CollectionFactory $userCollectionFactory
+ * @param Data $backendDataHelper
+ * @param NotificatorInterface|null $notificator
*/
public function __construct(
Context $context,
UserFactory $userFactory,
SecurityManager $securityManager,
CollectionFactory $userCollectionFactory = null,
- Data $backendDataHelper = null
+ Data $backendDataHelper = null,
+ ?NotificatorInterface $notificator = null
) {
parent::__construct($context, $userFactory);
$this->securityManager = $securityManager;
@@ -55,6 +71,8 @@ public function __construct(
ObjectManager::getInstance()->get(CollectionFactory::class);
$this->backendDataHelper = $backendDataHelper ?:
ObjectManager::getInstance()->get(Data::class);
+ $this->notificator = $notificator
+ ?? ObjectManager::getInstance()->get(NotificatorInterface::class);
}
/**
@@ -96,7 +114,7 @@ public function execute()
$newPassResetToken = $this->backendDataHelper->generateResetPasswordLinkToken();
$user->changeResetPasswordLinkToken($newPassResetToken);
$user->save();
- $user->sendPasswordResetConfirmationEmail();
+ $this->notificator->sendForgotPassword($user);
}
break;
}
diff --git a/app/code/Magento/User/Controller/Adminhtml/Locks/Index.php b/app/code/Magento/User/Controller/Adminhtml/Locks/Index.php
index 7c0e31076ca..e3e1e3def39 100644
--- a/app/code/Magento/User/Controller/Adminhtml/Locks/Index.php
+++ b/app/code/Magento/User/Controller/Adminhtml/Locks/Index.php
@@ -6,10 +6,12 @@
*/
namespace Magento\User\Controller\Adminhtml\Locks;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
/**
* Locks Index action
*/
-class Index extends \Magento\User\Controller\Adminhtml\Locks
+class Index extends \Magento\User\Controller\Adminhtml\Locks implements HttpGetActionInterface
{
/**
* Render page with grid
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Index.php b/app/code/Magento/User/Controller/Adminhtml/User/Index.php
index 7f79dd47737..bc4157c144a 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Index.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\User\Controller\Adminhtml\User;
-class Index extends \Magento\User\Controller\Adminhtml\User
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\User\Controller\Adminhtml\User implements HttpGetActionInterface
{
/**
* @return void
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/Index.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/Index.php
index e1853be17a1..8d468d45f1a 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Role/Index.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\User\Controller\Adminhtml\User\Role;
-class Index extends \Magento\User\Controller\Adminhtml\User\Role
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\User\Controller\Adminhtml\User\Role implements HttpGetActionInterface
{
/**
* Show grid with roles existing in systems
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/RoleGrid.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/RoleGrid.php
index 4d97b62cd8b..ad8c87b617d 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Role/RoleGrid.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/RoleGrid.php
@@ -6,7 +6,11 @@
*/
namespace Magento\User\Controller\Adminhtml\User\Role;
-class RoleGrid extends \Magento\User\Controller\Adminhtml\User\Role
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+use Magento\Framework\App\Action\HttpPostActionInterface;
+use Magento\User\Controller\Adminhtml\User\Role as RoleAction;
+
+class RoleGrid extends RoleAction implements HttpGetActionInterface, HttpPostActionInterface
{
/**
* Action for ajax request from grid
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
index 9dfe34e4353..44862f1fce2 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
@@ -7,6 +7,7 @@
namespace Magento\User\Controller\Adminhtml\User\Role;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Authorization\Model\Acl\Role\Group as RoleGroup;
use Magento\Authorization\Model\UserContextInterface;
use Magento\Framework\Controller\ResultFactory;
@@ -16,7 +17,7 @@
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class SaveRole extends \Magento\User\Controller\Adminhtml\User\Role
+class SaveRole extends \Magento\User\Controller\Adminhtml\User\Role implements HttpPostActionInterface
{
/**
* Session keys for Info form data
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/RoleGrid.php b/app/code/Magento/User/Controller/Adminhtml/User/RoleGrid.php
index 2bfbadd3a0d..e171f0a8c2b 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/RoleGrid.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/RoleGrid.php
@@ -6,7 +6,11 @@
*/
namespace Magento\User\Controller\Adminhtml\User;
-class RoleGrid extends \Magento\User\Controller\Adminhtml\User
+use Magento\Framework\App\Action\HttpGetActionInterface;
+use Magento\Framework\App\Action\HttpPostActionInterface;
+use Magento\User\Controller\Adminhtml\User as UserAction;
+
+class RoleGrid extends UserAction implements HttpGetActionInterface, HttpPostActionInterface
{
/**
* @return void
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Save.php b/app/code/Magento/User/Controller/Adminhtml/User/Save.php
index 4b984b761c1..521c09f7b77 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Save.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Save.php
@@ -6,14 +6,18 @@
namespace Magento\User\Controller\Adminhtml\User;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\Exception\AuthenticationException;
use Magento\Framework\Exception\State\UserLockedException;
use Magento\Security\Model\SecurityCookie;
+use Magento\User\Model\Spi\NotificationExceptionInterface;
/**
+ * Save admin user.
+ *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class Save extends \Magento\User\Controller\Adminhtml\User
+class Save extends \Magento\User\Controller\Adminhtml\User implements HttpPostActionInterface
{
/**
* @var SecurityCookie
@@ -36,7 +40,7 @@ private function getSecurityCookie()
}
/**
- * @return void
+ * @inheritDoc
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
@@ -44,10 +48,14 @@ public function execute()
{
$userId = (int)$this->getRequest()->getParam('user_id');
$data = $this->getRequest()->getPostValue();
+ if (array_key_exists('form_key', $data)) {
+ unset($data['form_key']);
+ }
if (!$data) {
$this->_redirect('adminhtml/*/');
return;
}
+
/** @var $model \Magento\User\Model\User */
$model = $this->_userFactory->create()->load($userId);
if ($userId && $model->isObjectNew()) {
@@ -87,17 +95,19 @@ public function execute()
$currentUser->performIdentityCheck($data[$currentUserPasswordField]);
$model->save();
- $model->sendNotificationEmailsIfRequired();
-
$this->messageManager->addSuccess(__('You saved the user.'));
$this->_getSession()->setUserData(false);
$this->_redirect('adminhtml/*/');
+
+ $model->sendNotificationEmailsIfRequired();
} catch (UserLockedException $e) {
$this->_auth->logout();
$this->getSecurityCookie()->setLogoutReasonCookie(
\Magento\Security\Model\AdminSessionsManager::LOGOUT_REASON_USER_LOCKED
);
$this->_redirect('adminhtml/*/');
+ } catch (NotificationExceptionInterface $exception) {
+ $this->messageManager->addErrorMessage($exception->getMessage());
} catch (\Magento\Framework\Exception\AuthenticationException $e) {
$this->messageManager->addError(
__('The password entered for the current user is invalid. Verify the password and try again.')
@@ -116,6 +126,8 @@ public function execute()
}
/**
+ * Redirect to Edit form.
+ *
* @param \Magento\User\Model\User $model
* @param array $data
* @return void
diff --git a/app/code/Magento/User/Model/Notificator.php b/app/code/Magento/User/Model/Notificator.php
new file mode 100644
index 00000000000..3a5522db4c5
--- /dev/null
+++ b/app/code/Magento/User/Model/Notificator.php
@@ -0,0 +1,194 @@
+transportBuilder = $transportBuilder;
+ $this->config = $config;
+ $this->deployConfig = $deployConfig;
+ $this->storeManager = $storeManager;
+ }
+
+ /**
+ * Send a notification.
+ *
+ * @param string $templateConfigId
+ * @param array $templateVars
+ * @param string $toEmail
+ * @param string $toName
+ * @throws MailException
+ *
+ * @return void
+ */
+ private function sendNotification(
+ string $templateConfigId,
+ array $templateVars,
+ string $toEmail,
+ string $toName
+ ): void {
+ $transport = $this->transportBuilder
+ ->setTemplateIdentifier($this->config->getValue($templateConfigId))
+ ->setTemplateModel(BackendTemplate::class)
+ ->setTemplateOptions([
+ 'area' => FrontNameResolver::AREA_CODE,
+ 'store' => Store::DEFAULT_STORE_ID
+ ])
+ ->setTemplateVars($templateVars)
+ ->setFrom(
+ $this->config->getValue('admin/emails/forgot_email_identity')
+ )
+ ->addTo($toEmail, $toName)
+ ->getTransport();
+ $transport->sendMessage();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function sendForgotPassword(UserInterface $user): void
+ {
+ try {
+ $this->sendNotification(
+ 'admin/emails/forgot_email_template',
+ [
+ 'user' => $user,
+ 'store' => $this->storeManager->getStore(
+ Store::DEFAULT_STORE_ID
+ )
+ ],
+ $user->getEmail(),
+ $user->getFirstName().' '.$user->getLastName()
+ );
+ } catch (LocalizedException $exception) {
+ throw new NotificatorException(
+ __($exception->getMessage()),
+ $exception
+ );
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function sendCreated(UserInterface $user): void
+ {
+ $toEmails = [];
+ $generalEmail = $this->config->getValue(
+ 'trans_email/ident_general/email'
+ );
+ if ($generalEmail) {
+ $toEmails[] = $generalEmail;
+ }
+ if ($adminEmail = $this->deployConfig->get('user_admin_email')) {
+ $toEmails[] = $adminEmail;
+ }
+
+ try {
+ foreach ($toEmails as $toEmail) {
+ $this->sendNotification(
+ 'admin/emails/new_user_notification_template',
+ [
+ 'user' => $user,
+ 'store' => $this->storeManager->getStore(
+ Store::DEFAULT_STORE_ID
+ )
+ ],
+ $toEmail,
+ __('Administrator')->getText()
+ );
+ }
+ } catch (LocalizedException $exception) {
+ throw new NotificatorException(
+ __($exception->getMessage()),
+ $exception
+ );
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function sendUpdated(UserInterface $user, array $changed): void
+ {
+ $email = $user->getEmail();
+ if ($user instanceof User) {
+ $email = $user->getOrigData('email');
+ }
+
+ try {
+ $this->sendNotification(
+ 'admin/emails/user_notification_template',
+ [
+ 'user' => $user,
+ 'store' => $this->storeManager->getStore(
+ Store::DEFAULT_STORE_ID
+ ),
+ 'changes' => implode(', ', $changed)
+ ],
+ $email,
+ $user->getFirstName().' '.$user->getLastName()
+ );
+ } catch (LocalizedException $exception) {
+ throw new NotificatorException(
+ __($exception->getMessage()),
+ $exception
+ );
+ }
+ }
+}
diff --git a/app/code/Magento/User/Model/NotificatorException.php b/app/code/Magento/User/Model/NotificatorException.php
new file mode 100644
index 00000000000..5b581879814
--- /dev/null
+++ b/app/code/Magento/User/Model/NotificatorException.php
@@ -0,0 +1,20 @@
+_encryptor = $encryptor;
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
@@ -166,7 +190,12 @@ public function __construct(
$this->_transportBuilder = $transportBuilder;
$this->_storeManager = $storeManager;
$this->validationRules = $validationRules;
- $this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class);
+ $this->serializer = $serializer
+ ?: ObjectManager::getInstance()->get(Json::class);
+ $this->deploymentConfig = $deploymentConfig
+ ?: ObjectManager::getInstance()->get(DeploymentConfig::class);
+ $this->notificator = $notificator
+ ?: ObjectManager::getInstance()->get(NotificatorInterface::class);
}
/**
@@ -180,6 +209,8 @@ protected function _construct()
}
/**
+ * Removing dependencies and leaving only entity's properties.
+ *
* @return string[]
*/
public function __sleep()
@@ -196,12 +227,18 @@ public function __sleep()
'_encryptor',
'_transportBuilder',
'_storeManager',
- '_validatorBeforeSave'
+ '_validatorBeforeSave',
+ 'validationRules',
+ 'serializer',
+ 'deploymentConfig',
+ 'notificator'
]
);
}
/**
+ * Restoring required objects after serialization.
+ *
* @return void
*/
public function __wakeup()
@@ -218,6 +255,9 @@ public function __wakeup()
$this->_encryptor = $objectManager->get(\Magento\Framework\Encryption\EncryptorInterface::class);
$this->_transportBuilder = $objectManager->get(\Magento\Framework\Mail\Template\TransportBuilder::class);
$this->_storeManager = $objectManager->get(\Magento\Store\Model\StoreManagerInterface::class);
+ $this->validationRules = $objectManager->get(UserValidationRules::class);
+ $this->deploymentConfig = $objectManager->get(DeploymentConfig::class);
+ $this->notificator = $objectManager->get(NotificatorInterface::class);
}
/**
@@ -388,7 +428,7 @@ public function deleteFromRole()
}
/**
- * Check if such combination role/user exists
+ * Check if such combination role/user exists.
*
* @return bool
*/
@@ -399,28 +439,24 @@ public function roleUserExists()
}
/**
- * Send email with reset password confirmation link
+ * Send email with reset password confirmation link.
+ *
+ * @deprecated
+ * @see NotificatorInterface::sendForgotPassword()
*
* @return $this
*/
public function sendPasswordResetConfirmationEmail()
{
- $templateId = $this->_config->getValue(self::XML_PATH_FORGOT_EMAIL_TEMPLATE);
- $transport = $this->_transportBuilder->setTemplateIdentifier($templateId)
- ->setTemplateModel(\Magento\Email\Model\BackendTemplate::class)
- ->setTemplateOptions(['area' => FrontNameResolver::AREA_CODE, 'store' => Store::DEFAULT_STORE_ID])
- ->setTemplateVars(['user' => $this, 'store' => $this->_storeManager->getStore(Store::DEFAULT_STORE_ID)])
- ->setFrom($this->_config->getValue(self::XML_PATH_FORGOT_EMAIL_IDENTITY))
- ->addTo($this->getEmail(), $this->getName())
- ->getTransport();
+ $this->notificator->sendForgotPassword($this);
- $transport->sendMessage();
return $this;
}
/**
* Send email to when password is resetting
*
+ * @throws NotificationExceptionInterface
* @return $this
* @deprecated 100.1.0
*/
@@ -431,20 +467,20 @@ public function sendPasswordResetNotificationEmail()
}
/**
- * Check changes and send notification emails
+ * Check changes and send notification emails.
*
+ * @throws NotificationExceptionInterface
* @return $this
* @since 100.1.0
*/
public function sendNotificationEmailsIfRequired()
{
- $changes = $this->createChangesDescriptionString();
-
- if ($changes) {
- if ($this->getEmail() != $this->getOrigData('email') && $this->getOrigData('email')) {
- $this->sendUserNotificationEmail($changes, $this->getOrigData('email'));
- }
- $this->sendUserNotificationEmail($changes);
+ if ($this->isObjectNew()) {
+ //Notification about a new user.
+ $this->notificator->sendCreated($this);
+ } elseif ($changes = $this->createChangesDescriptionString()) {
+ //User changed.
+ $this->notificator->sendUpdated($this, explode(', ', $changes));
}
return $this;
@@ -478,35 +514,21 @@ protected function createChangesDescriptionString()
}
/**
- * Send user notification email
+ * Send user notification email.
*
* @param string $changes
* @param string $email
+ * @throws NotificationExceptionInterface
* @return $this
* @since 100.1.0
+ * @deprecated
+ * @see NotificatorInterface::sendUpdated()
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function sendUserNotificationEmail($changes, $email = null)
{
- if ($email === null) {
- $email = $this->getEmail();
- }
+ $this->notificator->sendUpdated($this, explode(', ', $changes));
- $transport = $this->_transportBuilder
- ->setTemplateIdentifier($this->_config->getValue(self::XML_PATH_USER_NOTIFICATION_TEMPLATE))
- ->setTemplateModel(\Magento\Email\Model\BackendTemplate::class)
- ->setTemplateOptions(['area' => FrontNameResolver::AREA_CODE, 'store' => Store::DEFAULT_STORE_ID])
- ->setTemplateVars(
- [
- 'user' => $this,
- 'store' => $this->_storeManager->getStore(Store::DEFAULT_STORE_ID),
- 'changes' => $changes
- ]
- )
- ->setFrom($this->_config->getValue(self::XML_PATH_FORGOT_EMAIL_IDENTITY))
- ->addTo($email, $this->getName())
- ->getTransport();
-
- $transport->sendMessage();
return $this;
}
@@ -738,7 +760,7 @@ public function setHasAvailableResources($hasResources)
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function getFirstName()
{
@@ -746,7 +768,7 @@ public function getFirstName()
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function setFirstName($firstName)
{
@@ -754,7 +776,7 @@ public function setFirstName($firstName)
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function getLastName()
{
@@ -762,7 +784,7 @@ public function getLastName()
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function setLastName($lastName)
{
@@ -770,7 +792,7 @@ public function setLastName($lastName)
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function getEmail()
{
@@ -778,7 +800,7 @@ public function getEmail()
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function setEmail($email)
{
@@ -786,7 +808,7 @@ public function setEmail($email)
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function getUserName()
{
@@ -794,7 +816,7 @@ public function getUserName()
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function setUserName($userName)
{
@@ -802,7 +824,7 @@ public function setUserName($userName)
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function getPassword()
{
@@ -810,7 +832,7 @@ public function getPassword()
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function setPassword($password)
{
@@ -818,7 +840,7 @@ public function setPassword($password)
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function getCreated()
{
@@ -826,7 +848,7 @@ public function getCreated()
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function setCreated($created)
{
@@ -834,7 +856,7 @@ public function setCreated($created)
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function getModified()
{
@@ -842,7 +864,7 @@ public function getModified()
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function setModified($modified)
{
@@ -850,7 +872,7 @@ public function setModified($modified)
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function getIsActive()
{
@@ -858,7 +880,7 @@ public function getIsActive()
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function setIsActive($isActive)
{
@@ -866,7 +888,7 @@ public function setIsActive($isActive)
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function getInterfaceLocale()
{
@@ -874,7 +896,7 @@ public function getInterfaceLocale()
}
/**
- * {@inheritdoc}
+ * @inheritDoc
*/
public function setInterfaceLocale($interfaceLocale)
{
diff --git a/app/code/Magento/User/Test/Unit/Model/UserTest.php b/app/code/Magento/User/Test/Unit/Model/UserTest.php
index 4bc5db138c7..670316c2500 100644
--- a/app/code/Magento/User/Test/Unit/Model/UserTest.php
+++ b/app/code/Magento/User/Test/Unit/Model/UserTest.php
@@ -6,7 +6,9 @@
namespace Magento\User\Test\Unit\Model;
-use Magento\Framework\Serialize\Serializer\Json;
+use Magento\User\Helper\Data as UserHelper;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\User\Model\User;
/**
* Test class for \Magento\User\Model\User testing
@@ -16,55 +18,11 @@
*/
class UserTest extends \PHPUnit\Framework\TestCase
{
- /** @var \Magento\User\Model\User */
- protected $model;
+ /** @var User */
+ private $model;
- /** @var \Magento\User\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
- protected $userDataMock;
-
- /** @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject */
- protected $transportBuilderMock;
-
- /** @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject */
- protected $contextMock;
-
- /** @var \Magento\User\Model\ResourceModel\User|\PHPUnit_Framework_MockObject_MockObject */
- protected $resourceMock;
-
- /** @var \Magento\Framework\Data\Collection\AbstractDb|\PHPUnit_Framework_MockObject_MockObject */
- protected $collectionMock;
-
- /** @var \Magento\Framework\Mail\TransportInterface|\PHPUnit_Framework_MockObject_MockObject */
- protected $transportMock;
-
- /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
- protected $storeManagerMock;
-
- /** @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject */
- protected $storeMock;
-
- /** @var \Magento\Backend\App\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
- protected $configMock;
-
- /** @var \Magento\Framework\Encryption\EncryptorInterface|\PHPUnit_Framework_MockObject_MockObject */
- protected $encryptorMock;
-
- /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
- protected $eventManagerMock;
-
- /** @var \Magento\Framework\Validator\DataObjectFactory|\PHPUnit_Framework_MockObject_MockObject */
- protected $validatorObjectFactoryMock;
-
- /** @var \Magento\User\Model\UserValidationRules|\PHPUnit_Framework_MockObject_MockObject */
- protected $validationRulesMock;
-
- /** @var \Magento\Authorization\Model\RoleFactory|\PHPUnit_Framework_MockObject_MockObject */
- protected $roleFactoryMock;
-
- /**
- * @var Json|\PHPUnit_Framework_MockObject_MockObject
- */
- private $serializer;
+ /** @var UserHelper|\PHPUnit_Framework_MockObject_MockObject */
+ private $userDataMock;
/**
* Set required values
@@ -72,308 +30,20 @@ class UserTest extends \PHPUnit\Framework\TestCase
*/
protected function setUp()
{
- $this->userDataMock = $this->getMockBuilder(\Magento\User\Helper\Data::class)
+ $this->userDataMock = $this->getMockBuilder(UserHelper::class)
->disableOriginalConstructor()
->setMethods([])
->getMock();
- $this->contextMock = $this->getMockBuilder(\Magento\Framework\Model\Context::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->resourceMock = $this->getMockBuilder(\Magento\User\Model\ResourceModel\User::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->collectionMock = $this->getMockBuilder(\Magento\Framework\Data\Collection\AbstractDb::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMockForAbstractClass();
- $coreRegistry = $this->getMockBuilder(\Magento\Framework\Registry::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class)
- ->disableOriginalConstructor()
- ->setMethods(['dispatch'])
- ->getMockForAbstractClass();
- $this->validatorObjectFactoryMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObjectFactory::class)
- ->disableOriginalConstructor()->setMethods(['create'])
- ->getMock();
- $this->roleFactoryMock = $this->getMockBuilder(\Magento\Authorization\Model\RoleFactory::class)
- ->disableOriginalConstructor()
- ->setMethods(['create'])
- ->getMock();
- $this->transportMock = $this->getMockBuilder(\Magento\Framework\Mail\TransportInterface::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->transportBuilderMock = $this->getMockBuilder(\Magento\Framework\Mail\Template\TransportBuilder::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
-
- $this->configMock = $this->getMockBuilder(\Magento\Backend\App\ConfigInterface::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
-
- $this->validationRulesMock = $this->getMockBuilder(\Magento\User\Model\UserValidationRules::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
-
- $this->encryptorMock = $this->getMockBuilder(\Magento\Framework\Encryption\EncryptorInterface::class)
- ->setMethods(['validateHash'])
- ->getMockForAbstractClass();
-
- $this->serializer = $this->createPartialMock(Json::class, ['serialize', 'unserialize']);
- $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+ $objectManagerHelper = new ObjectManager($this);
$this->model = $objectManagerHelper->getObject(
- \Magento\User\Model\User::class,
+ User::class,
[
- 'eventManager' => $this->eventManagerMock,
'userData' => $this->userDataMock,
- 'registry' => $coreRegistry,
- 'resource' => $this->resourceMock,
- 'resourceCollection' => $this->collectionMock,
- 'validatorObjectFactory' => $this->validatorObjectFactoryMock,
- 'roleFactory' => $this->roleFactoryMock,
- 'transportBuilder' => $this->transportBuilderMock,
- 'storeManager' => $this->storeManagerMock,
- 'validationRules' => $this->validationRulesMock,
- 'config' => $this->configMock,
- 'encryptor' => $this->encryptorMock,
- 'serializer' => $this->serializer
]
);
}
- /**
- * @return void
- */
- public function testSendNotificationEmailsIfRequired()
- {
- $storeId = 0;
- $email = 'test1@example.com';
- $origEmail = 'test2@example.com';
-
- $password = '1234567';
- $origPassword = '123456789';
-
- $username = 'admin1';
- $origUsername = 'admin2';
-
- $firstName = 'Foo';
- $lastName = 'Bar';
-
- $changes = __('email') . ', ' . __('password') . ', ' . __('username');
-
- $this->model->setEmail($email);
- $this->model->setOrigData('email', $origEmail);
-
- $this->model->setPassword($password);
- $this->model->setOrigData('password', $origPassword);
-
- $this->model->setUserName($username);
- $this->model->setOrigData('username', $origUsername);
-
- $this->model->setFirstName($firstName);
- $this->model->setLastName($lastName);
-
- $this->configMock->expects($this->exactly(4))
- ->method('getValue')
- ->withConsecutive(
- [\Magento\User\Model\User::XML_PATH_USER_NOTIFICATION_TEMPLATE],
- [\Magento\User\Model\User::XML_PATH_FORGOT_EMAIL_IDENTITY],
- [\Magento\User\Model\User::XML_PATH_USER_NOTIFICATION_TEMPLATE],
- [\Magento\User\Model\User::XML_PATH_FORGOT_EMAIL_IDENTITY]
- )->willReturnOnConsecutiveCalls(
- 'templateId',
- 'sender',
- 'templateId',
- 'sender'
- );
-
- $this->transportBuilderMock->expects($this->exactly(2))
- ->method('setTemplateModel')
- ->with($this->equalTo(\Magento\Email\Model\BackendTemplate::class))
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->exactly(2))
- ->method('setTemplateOptions')
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->exactly(2))
- ->method('setTemplateVars')
- ->with(['user' => $this->model, 'store' => $this->storeMock, 'changes' => $changes])
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->exactly(2))
- ->method('addTo')
- ->withConsecutive(
- $this->equalTo($email),
- $this->equalTo($firstName . ' ' . $lastName),
- $this->equalTo($origEmail),
- $this->equalTo($firstName . ' ' . $lastName)
- )
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->exactly(2))
- ->method('setFrom')
- ->with('sender')
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->exactly(2))
- ->method('setTemplateIdentifier')
- ->with('templateId')
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->exactly(2))
- ->method('getTransport')
- ->willReturn($this->transportMock);
- $this->transportMock->expects($this->exactly(2))->method('sendMessage');
-
- $this->storeManagerMock->expects($this->exactly(2))
- ->method('getStore')
- ->with($storeId)
- ->willReturn($this->storeMock);
-
- $this->assertInstanceOf(\Magento\User\Model\User::class, $this->model->sendNotificationEmailsIfRequired());
- }
-
- /**
- * @return void
- */
- public function testSendPasswordResetConfirmationEmail()
- {
- $storeId = 0;
- $email = 'test@example.com';
- $firstName = 'Foo';
- $lastName = 'Bar';
-
- $this->model->setEmail($email);
- $this->model->setFirstName($firstName);
- $this->model->setLastName($lastName);
-
- $this->configMock->expects($this->at(0))
- ->method('getValue')
- ->with(\Magento\User\Model\User::XML_PATH_FORGOT_EMAIL_TEMPLATE)
- ->willReturn('templateId');
- $this->configMock->expects($this->at(1))
- ->method('getValue')
- ->with(\Magento\User\Model\User::XML_PATH_FORGOT_EMAIL_IDENTITY)
- ->willReturn('sender');
- $this->transportBuilderMock->expects($this->once())
- ->method('setTemplateModel')
- ->with($this->equalTo(\Magento\Email\Model\BackendTemplate::class))
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->once())
- ->method('setTemplateOptions')
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->once())
- ->method('setTemplateVars')
- ->with(['user' => $this->model, 'store' => $this->storeMock])
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->once())
- ->method('addTo')
- ->with($this->equalTo($email), $this->equalTo($firstName . ' ' . $lastName))
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->once())
- ->method('setFrom')
- ->with('sender')
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->once())
- ->method('setTemplateIdentifier')
- ->with('templateId')
- ->willReturnSelf();
- $this->transportBuilderMock->expects($this->once())
- ->method('getTransport')
- ->willReturn($this->transportMock);
- $this->transportMock->expects($this->once())->method('sendMessage');
-
- $this->storeManagerMock->expects($this->once())
- ->method('getStore')
- ->with($storeId)
- ->willReturn($this->storeMock);
-
- $this->assertInstanceOf(\Magento\User\Model\User::class, $this->model->sendPasswordResetConfirmationEmail());
- }
-
- /**
- * @return void
- */
- public function testVerifyIdentity()
- {
- $password = 'password';
- $this->encryptorMock
- ->expects($this->once())
- ->method('validateHash')
- ->with($password, $this->model->getPassword())
- ->willReturn(true);
- $this->model->setIsActive(true);
- $this->resourceMock->expects($this->once())->method('hasAssigned2Role')->willReturn(true);
- $this->assertTrue(
- $this->model->verifyIdentity($password),
- 'Identity verification failed while should have passed.'
- );
- }
-
- /**
- * @return void
- */
- public function testVerifyIdentityFailure()
- {
- $password = 'password';
- $this->encryptorMock
- ->expects($this->once())
- ->method('validateHash')
- ->with($password, $this->model->getPassword())
- ->willReturn(false);
- $this->assertFalse(
- $this->model->verifyIdentity($password),
- 'Identity verification passed while should have failed.'
- );
- }
-
- /**
- * @return void
- */
- public function testVerifyIdentityInactiveRecord()
- {
- $password = 'password';
- $this->encryptorMock
- ->expects($this->once())
- ->method('validateHash')
- ->with($password, $this->model->getPassword())
- ->willReturn(true);
- $this->model->setIsActive(false);
- $this->expectException(\Magento\Framework\Exception\AuthenticationException::class);
- $this->expectExceptionMessage('The account sign-in was incorrect or your account is disabled temporarily. '
- . 'Please wait and try again later.');
- $this->model->verifyIdentity($password);
- }
-
- /**
- * @return void
- */
- public function testVerifyIdentityNoAssignedRoles()
- {
- $password = 'password';
- $this->encryptorMock
- ->expects($this->once())
- ->method('validateHash')
- ->with($password, $this->model->getPassword())
- ->willReturn(true);
- $this->model->setIsActive(true);
- $this->resourceMock->expects($this->once())->method('hasAssigned2Role')->willReturn(false);
- $this->expectException(\Magento\Framework\Exception\AuthenticationException::class);
- $this->expectExceptionMessage('More permissions are needed to access this.');
- $this->model->verifyIdentity($password);
- }
-
/**
* @return void
*/
@@ -399,225 +69,21 @@ public function testSleep()
$this->assertEmpty($expectedResult);
}
- /**
- * @return void
- */
- public function testBeforeSave()
- {
- $this->eventManagerMock->expects($this->any())->method('dispatch');
- $this->model->setIsActive(1);
- $actualData = $this->model->beforeSave()->getData();
- $this->assertArrayHasKey('extra', $actualData);
- $this->assertArrayHasKey('password', $actualData);
- $this->assertArrayHasKey('is_active', $actualData);
- }
-
- /**
- * @return void
- */
- public function testValidateOk()
- {
- /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */
- $validatorMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObject::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock);
- $this->validationRulesMock->expects($this->once())
- ->method('addUserInfoRules')
- ->with($validatorMock);
- $validatorMock->expects($this->once())->method('isValid')->willReturn(true);
- $this->assertTrue($this->model->validate());
- }
-
- /**
- * @return void
- */
- public function testValidateInvalid()
- {
- $messages = ['Invalid username'];
- /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */
- $validatorMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObject::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock);
- $this->validationRulesMock->expects($this->once())
- ->method('addUserInfoRules')
- ->with($validatorMock);
- $validatorMock->expects($this->once())->method('isValid')->willReturn(false);
- $validatorMock->expects($this->once())->method('getMessages')->willReturn($messages);
- $this->assertEquals($messages, $this->model->validate());
- }
-
- /**
- * @return void
- */
- public function testSaveExtra()
- {
- $data = [1, 2, 3];
- $this->resourceMock->expects($this->once())
- ->method('saveExtra')
- ->with($this->model, json_encode($data));
-
- $this->serializer->expects($this->once())
- ->method('serialize')
- ->with($data)
- ->will($this->returnValue(json_encode($data)));
-
- $this->assertInstanceOf(\Magento\User\Model\User::class, $this->model->saveExtra($data));
- }
-
- /**
- * @return void
- */
- public function testGetRoles()
- {
- $this->resourceMock->expects($this->once())->method('getRoles')->with($this->model)->willReturn([]);
- $this->assertInternalType('array', $this->model->getRoles());
- }
-
- /**
- * @return void
- */
- public function testGetRole()
- {
- $roles = ['role'];
- $roleMock = $this->getMockBuilder(\Magento\Authorization\Model\Role::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->roleFactoryMock->expects($this->once())->method('create')->willReturn($roleMock);
- $this->resourceMock->expects($this->once())->method('getRoles')->with($this->model)->willReturn($roles);
- $roleMock->expects($this->once())->method('load')->with($roles[0]);
- $this->assertInstanceOf(\Magento\Authorization\Model\Role::class, $this->model->getRole());
- }
-
- /**
- * @return void
- */
- public function testDeleteFromRole()
- {
- $this->resourceMock->expects($this->once())->method('deleteFromRole')->with($this->model);
- $this->assertInstanceOf(\Magento\User\Model\User::class, $this->model->deleteFromRole());
- }
-
- /**
- * @return void
- */
- public function testRoleUserExistsTrue()
- {
- $result = ['role'];
- $this->resourceMock->expects($this->once())->method('roleUserExists')->with($this->model)->willReturn($result);
- $this->assertTrue($this->model->roleUserExists());
- }
-
- /**
- * @return void
- */
- public function testRoleUserExistsFalse()
- {
- $result = [];
- $this->resourceMock->expects($this->once())->method('roleUserExists')->with($this->model)->willReturn($result);
- $this->assertFalse($this->model->roleUserExists());
- }
-
- /**
- * @return void
- */
- public function testGetAclRole()
- {
- $roles = ['role'];
- $result = 1;
- $roleMock = $this->getMockBuilder(\Magento\Authorization\Model\Role::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->roleFactoryMock->expects($this->once())->method('create')->willReturn($roleMock);
- $this->resourceMock->expects($this->once())->method('getRoles')->with($this->model)->willReturn($roles);
- $roleMock->expects($this->once())->method('load')->with($roles[0]);
- $roleMock->expects($this->once())->method('getId')->willReturn($result);
- $this->assertEquals($result, $this->model->getAclRole());
- }
-
- /**
- * @dataProvider authenticateDataProvider
- * @param string $usernameIn
- * @param string $usernameOut
- * @param bool $expectedResult
- * @return void
- */
- public function testAuthenticate($usernameIn, $usernameOut, $expectedResult)
- {
- $password = 'password';
- $config = 'config';
-
- $data = ['id' => 1, 'is_active' => 1, 'username' => $usernameOut];
-
- $this->configMock->expects($this->once())
- ->method('isSetFlag')
- ->with('admin/security/use_case_sensitive_login')
- ->willReturn($config);
- $this->eventManagerMock->expects($this->any())->method('dispatch');
-
- $this->resourceMock->expects($this->any())->method('loadByUsername')->willReturn($data);
- $this->model->setIdFieldName('id');
-
- $this->encryptorMock->expects($this->any())->method('validateHash')->willReturn(true);
- $this->resourceMock->expects($this->any())->method('hasAssigned2Role')->willReturn(true);
- $this->assertEquals($expectedResult, $this->model->authenticate($usernameIn, $password));
- }
-
- /**
- * @return array
- */
- public function authenticateDataProvider()
- {
- return [
- 'success' => [
- 'usernameIn' => 'username',
- 'usernameOut' => 'username',
- 'expectedResult' => true
- ],
- 'failedUsername' => [
- 'usernameIn' => 'username1',
- 'usernameOut' => 'username2',
- 'expectedResult' => false
- ]
- ];
- }
-
- /**
- * @expectedException \Magento\Framework\Exception\LocalizedException
- * @return void
- */
- public function testAuthenticateException()
- {
- $username = 'username';
- $password = 'password';
- $config = 'config';
-
- $this->configMock->expects($this->once())
- ->method('isSetFlag')
- ->with('admin/security/use_case_sensitive_login')
- ->willReturn($config);
-
- $this->eventManagerMock->expects($this->any())->method('dispatch');
- $this->resourceMock->expects($this->once())
- ->method('loadByUsername')
- ->willThrowException(new \Magento\Framework\Exception\LocalizedException(__()));
- $this->model->authenticate($username, $password);
- }
-
/**
* @return void
*/
public function testChangeResetPasswordLinkToken()
{
$token = '1';
- $this->assertInstanceOf(\Magento\User\Model\User::class, $this->model->changeResetPasswordLinkToken($token));
+ $this->assertInstanceOf(
+ User::class,
+ $this->model->changeResetPasswordLinkToken($token)
+ );
$this->assertEquals($token, $this->model->getRpToken());
- $this->assertInternalType('string', $this->model->getRpTokenCreatedAt());
+ $this->assertInternalType(
+ 'string',
+ $this->model->getRpTokenCreatedAt()
+ );
}
/**
@@ -640,168 +106,4 @@ public function testIsResetPasswordLinkTokenExpiredIsExpiredToken()
$this->userDataMock->expects($this->once())->method('getResetPasswordLinkExpirationPeriod')->willReturn(0);
$this->assertTrue($this->model->isResetPasswordLinkTokenExpired());
}
-
- /**
- * @return void
- */
- public function testIsResetPasswordLinkTokenExpiredIsNotExpiredToken()
- {
- $this->model->setRpToken('1');
- $this->model->setRpTokenCreatedAt(
- (new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT)
- );
- $this->userDataMock->expects($this->once())->method('getResetPasswordLinkExpirationPeriod')->willReturn(1);
- $this->assertFalse($this->model->isResetPasswordLinkTokenExpired());
- }
-
- public function testCheckPasswordChangeEqualToCurrent()
- {
- /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */
- $validatorMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObject::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock);
- $this->validationRulesMock->expects($this->once())
- ->method('addUserInfoRules')
- ->with($validatorMock);
- $validatorMock->expects($this->once())->method('isValid')->willReturn(true);
-
- $newPassword = "NEWmYn3wpassw0rd";
- $oldPassword = "OLDmYn3wpassw0rd";
- $this->model->setPassword($newPassword)
- ->setId(1)
- ->setOrigData('password', $oldPassword);
- $this->encryptorMock->expects($this->once())
- ->method('isValidHash')
- ->with($newPassword, $oldPassword)
- ->willReturn(true);
- $result = $this->model->validate();
- $this->assertInternalType('array', $result);
- $this->assertCount(1, $result);
- $this->assertContains("Sorry, but this password has already been used.", (string)$result[0]);
- }
-
- public function testCheckPasswordChangeEqualToPrevious()
- {
- /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */
- $validatorMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObject::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock);
- $this->validationRulesMock->expects($this->once())
- ->method('addUserInfoRules')
- ->with($validatorMock);
- $validatorMock->expects($this->once())->method('isValid')->willReturn(true);
-
- $newPassword = "NEWmYn3wpassw0rd";
- $newPasswordHash = "new password hash";
- $oldPassword = "OLDmYn3wpassw0rd";
- $this->model->setPassword($newPassword)
- ->setId(1)
- ->setOrigData('password', $oldPassword);
- $this->encryptorMock->expects($this->atLeastOnce())
- ->method('isValidHash')
- ->will($this->onConsecutiveCalls(false, true));
-
- $this->resourceMock->expects($this->once())->method('getOldPasswords')->willReturn(['hash1', $newPasswordHash]);
-
- $result = $this->model->validate();
- $this->assertInternalType('array', $result);
- $this->assertCount(1, $result);
- $this->assertContains("Sorry, but this password has already been used.", (string)$result[0]);
- }
-
- public function testCheckPasswordChangeValid()
- {
- /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */
- $validatorMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObject::class)
- ->disableOriginalConstructor()
- ->setMethods([])
- ->getMock();
- $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock);
- $this->validationRulesMock->expects($this->once())
- ->method('addUserInfoRules')
- ->with($validatorMock);
- $validatorMock->expects($this->once())->method('isValid')->willReturn(true);
-
- $newPassword = "NEWmYn3wpassw0rd";
- $oldPassword = "OLDmYn3wpassw0rd";
- $this->model->setPassword($newPassword)
- ->setId(1)
- ->setOrigData('password', $oldPassword);
- $this->encryptorMock->expects($this->atLeastOnce())
- ->method('isValidHash')
- ->will($this->onConsecutiveCalls(false, false, false));
-
- $this->resourceMock->expects($this->once())->method('getOldPasswords')->willReturn(['hash1', 'hash2']);
-
- $result = $this->model->validate();
- $this->assertTrue($result);
- }
-
- /**
- * Test for performIdentityCheck method
- *
- * @param bool $verifyIdentityResult
- * @param bool $lockExpires
- * @dataProvider dataProviderPerformIdentityCheck
- */
- public function testPerformIdentityCheck($verifyIdentityResult, $lockExpires)
- {
- $password = 'qwerty1';
- $userName = 'John Doe';
-
- $this->encryptorMock
- ->expects($this->once())
- ->method('validateHash')
- ->with($password, $this->model->getPassword())
- ->willReturn($verifyIdentityResult);
- $this->model->setIsActive(true);
- $this->resourceMock->expects($this->any())->method('hasAssigned2Role')->willReturn(true);
-
- $this->model->setUserName($userName);
- $this->model->setLockExpires($lockExpires);
-
- $this->eventManagerMock->expects($this->any())
- ->method('dispatch')
- ->with(
- 'admin_user_authenticate_after',
- [
- 'username' => $userName,
- 'password' => $password,
- 'user' => $this->model,
- 'result' => $verifyIdentityResult
- ]
- )
- ->willReturnSelf();
-
- if ($lockExpires) {
- $this->expectException(\Magento\Framework\Exception\State\UserLockedException::class);
- $this->expectExceptionMessage((string)__('Your account is temporarily disabled. Please try again later.'));
- }
-
- if (!$lockExpires && !$verifyIdentityResult) {
- $this->expectException(\Magento\Framework\Exception\AuthenticationException::class);
- $this->expectExceptionMessage(
- (string)__('The password entered for the current user is invalid. Verify the password and try again.')
- );
- }
-
- $this->model->performIdentityCheck($password);
- }
-
- /**
- * @return array
- */
- public function dataProviderPerformIdentityCheck()
- {
- return [
- ['verifyIdentityResult' => true, 'lockExpires' => false],
- ['verifyIdentityResult' => false, 'lockExpires' => false],
- ['verifyIdentityResult' => true, 'lockExpires' => true],
- ['verifyIdentityResult' => false, 'lockExpires' => true]
- ];
- }
}
diff --git a/app/code/Magento/User/etc/config.xml b/app/code/Magento/User/etc/config.xml
index f6a3924b5a2..c1f51bcbece 100644
--- a/app/code/Magento/User/etc/config.xml
+++ b/app/code/Magento/User/etc/config.xml
@@ -10,6 +10,7 @@
admin_emails_forgot_email_template
+ admin_emails_new_user_notification_template
general
admin_emails_user_notification_template
diff --git a/app/code/Magento/User/etc/di.xml b/app/code/Magento/User/etc/di.xml
index b92549b54da..8fc85bc19e5 100644
--- a/app/code/Magento/User/etc/di.xml
+++ b/app/code/Magento/User/etc/di.xml
@@ -17,4 +17,5 @@
+
diff --git a/app/code/Magento/User/etc/email_templates.xml b/app/code/Magento/User/etc/email_templates.xml
index b998f304c24..637c2b799f3 100644
--- a/app/code/Magento/User/etc/email_templates.xml
+++ b/app/code/Magento/User/etc/email_templates.xml
@@ -8,4 +8,10 @@
+
diff --git a/app/code/Magento/User/view/adminhtml/email/new_user_notification.html b/app/code/Magento/User/view/adminhtml/email/new_user_notification.html
new file mode 100644
index 00000000000..891faf5fb8c
--- /dev/null
+++ b/app/code/Magento/User/view/adminhtml/email/new_user_notification.html
@@ -0,0 +1,18 @@
+
+
+
+
+{{trans "Hello,"}}
+
+{{trans "A new admin account was created for %first_name, %last_name using %email." first_name=$user.first_name last_name=$user.last_name email=$user.email}}
+{{trans "If you have not authorized this action, please contact us immediately at %store_email" store_email=$store_email |escape}}{{depend store_phone}} {{trans "or call us at %store_phone" store_phone=$store_phone |escape}}{{/depend}}.
+
+{{trans "Thanks,"}}
+{{var store.getFrontendName()}}
diff --git a/app/code/Magento/Variable/Controller/Adminhtml/System/Variable/Index.php b/app/code/Magento/Variable/Controller/Adminhtml/System/Variable/Index.php
index f70cb31eb54..71cb76a67d1 100644
--- a/app/code/Magento/Variable/Controller/Adminhtml/System/Variable/Index.php
+++ b/app/code/Magento/Variable/Controller/Adminhtml/System/Variable/Index.php
@@ -6,12 +6,14 @@
*/
namespace Magento\Variable\Controller\Adminhtml\System\Variable;
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
/**
* Display Variables list page
* @api
* @since 100.0.2
*/
-class Index extends \Magento\Variable\Controller\Adminhtml\System\Variable
+class Index extends \Magento\Variable\Controller\Adminhtml\System\Variable implements HttpGetActionInterface
{
/**
* Index Action
diff --git a/app/code/Magento/Vault/etc/db_schema.xml b/app/code/Magento/Vault/etc/db_schema.xml
index ed1f2adba21..e9645e211ae 100644
--- a/app/code/Magento/Vault/etc/db_schema.xml
+++ b/app/code/Magento/Vault/etc/db_schema.xml
@@ -9,7 +9,7 @@
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
+ comment="Entity ID"/>
getMethodsMap()->getMethodsMap($paramObjectType)
diff --git a/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php b/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php
index e6df38c563e..e74db459808 100644
--- a/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php
+++ b/app/code/Magento/WebapiAsync/Controller/Rest/Asynchronous/InputParamsResolver.php
@@ -95,6 +95,13 @@ public function resolve()
$this->requestValidator->validate();
$webapiResolvedParams = [];
$inputData = $this->request->getRequestData();
+
+ $httpMethod = $this->request->getHttpMethod();
+ if ($httpMethod == \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE) {
+ $requestBodyParams = $this->request->getBodyParams();
+ $inputData = array_merge($requestBodyParams, $inputData);
+ }
+
foreach ($inputData as $key => $singleEntityParams) {
$webapiResolvedParams[$key] = $this->resolveBulkItemParams($singleEntityParams);
}
@@ -103,6 +110,8 @@ public function resolve()
}
/**
+ * Returns route.
+ *
* @return \Magento\Webapi\Controller\Rest\Router\Route
*/
public function getRoute()
@@ -111,8 +120,7 @@ public function getRoute()
}
/**
- * Convert the input array from key-value format to a list of parameters
- * suitable for the specified class / method.
+ * Convert the input array from key-value format to a list of parameters suitable for the specified class / method.
*
* Instead of \Magento\Webapi\Controller\Rest\InputParamsResolver
* we don't need to merge body params with url params and use only body params
diff --git a/app/code/Magento/Weee/Plugin/Catalog/Controller/Adminhtml/Product/Initialization/Helper/ProcessTaxAttribute.php b/app/code/Magento/Weee/Plugin/Catalog/Controller/Adminhtml/Product/Initialization/Helper/ProcessTaxAttribute.php
new file mode 100644
index 00000000000..4aa941cd137
--- /dev/null
+++ b/app/code/Magento/Weee/Plugin/Catalog/Controller/Adminhtml/Product/Initialization/Helper/ProcessTaxAttribute.php
@@ -0,0 +1,60 @@
+request = $request;
+ }
+
+ /**
+ * Handles product tax attributes data initialization.
+ *
+ * @param Helper $subject
+ * @param Product $result
+ * @param Product $product
+ * @param array $productData
+ * @return Product
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function afterInitializeFromData(
+ Helper $subject,
+ Product $result,
+ Product $product,
+ array $productData
+ ): Product {
+ $attributes = $result->getAttributes();
+ if (!empty($attributes)) {
+ foreach ($attributes as $attribute) {
+ if ($attribute->getFrontendInput() == 'weee' && !isset($productData[$attribute->getAttributeCode()])) {
+ $result->setData($attribute->getAttributeCode(), []);
+ }
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/app/code/Magento/Weee/Test/Mftf/Section/AdminProductAddFPTValueSection.xml b/app/code/Magento/Weee/Test/Mftf/Section/AdminProductAddFPTValueSection.xml
index eee3f421910..ebf9f410471 100644
--- a/app/code/Magento/Weee/Test/Mftf/Section/AdminProductAddFPTValueSection.xml
+++ b/app/code/Magento/Weee/Test/Mftf/Section/AdminProductAddFPTValueSection.xml
@@ -10,6 +10,7 @@
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
+
diff --git a/app/code/Magento/Weee/Test/Mftf/Test/AdminRemoveProductWeeeAttributeOptionTest.xml b/app/code/Magento/Weee/Test/Mftf/Test/AdminRemoveProductWeeeAttributeOptionTest.xml
new file mode 100644
index 00000000000..2e3467fe2c7
--- /dev/null
+++ b/app/code/Magento/Weee/Test/Mftf/Test/AdminRemoveProductWeeeAttributeOptionTest.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Weee/Ui/DataProvider/Product/Form/Modifier/Weee.php b/app/code/Magento/Weee/Ui/DataProvider/Product/Form/Modifier/Weee.php
index c96a7a02003..d05b8c21689 100644
--- a/app/code/Magento/Weee/Ui/DataProvider/Product/Form/Modifier/Weee.php
+++ b/app/code/Magento/Weee/Ui/DataProvider/Product/Form/Modifier/Weee.php
@@ -85,7 +85,7 @@ public function __construct(
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function modifyData(array $data)
{
@@ -93,7 +93,7 @@ public function modifyData(array $data)
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function modifyMeta(array $meta)
{
@@ -155,6 +155,7 @@ protected function modifyAttributeConfig($attributeCode, array $attributeConfig)
'dndConfig' => [
'enabled' => false,
],
+ 'required' => (bool)$attributeConfig['arguments']['data']['config']['required'],
],
],
],
@@ -180,6 +181,7 @@ protected function modifyAttributeConfig($attributeCode, array $attributeConfig)
'component' => 'Magento_Weee/js/fpt-group',
'visible' => true,
'label' => __('Country/State'),
+ 'showLabel' => false,
],
],
],
@@ -197,6 +199,7 @@ protected function modifyAttributeConfig($attributeCode, array $attributeConfig)
'validation' => [
'required-entry' => true,
],
+ 'showLabel' => false,
],
],
],
@@ -216,6 +219,7 @@ protected function modifyAttributeConfig($attributeCode, array $attributeConfig)
],
'caption' => '*',
'visible' => true,
+ 'showLabel' => false,
],
],
],
@@ -233,6 +237,7 @@ protected function modifyAttributeConfig($attributeCode, array $attributeConfig)
'validation' => [
'validate-fpt-group' => true
],
+ 'showLabel' => false,
],
],
],
@@ -252,6 +257,7 @@ protected function modifyAttributeConfig($attributeCode, array $attributeConfig)
'validation' => [
'required-entry' => true
],
+ 'showLabel' => false,
],
],
],
@@ -267,6 +273,7 @@ protected function modifyAttributeConfig($attributeCode, array $attributeConfig)
'label' => __('Website'),
'visible' => $this->websiteManager->isMultiWebsites(),
'options' => $this->websiteManager->getWebsites($product, $eavAttribute),
+ 'showLabel' => false,
],
],
],
diff --git a/app/code/Magento/Weee/etc/db_schema.xml b/app/code/Magento/Weee/etc/db_schema.xml
index 96c3be9740e..49b201acb33 100644
--- a/app/code/Magento/Weee/etc/db_schema.xml
+++ b/app/code/Magento/Weee/etc/db_schema.xml
@@ -13,7 +13,7 @@
+ default="0" comment="Entity ID"/>
diff --git a/app/code/Magento/Weee/etc/di.xml b/app/code/Magento/Weee/etc/di.xml
index e52aebd3af8..8b433163cad 100644
--- a/app/code/Magento/Weee/etc/di.xml
+++ b/app/code/Magento/Weee/etc/di.xml
@@ -78,4 +78,7 @@
+
+
+
diff --git a/app/code/Magento/Widget/Block/Adminhtml/Widget/Chooser.php b/app/code/Magento/Widget/Block/Adminhtml/Widget/Chooser.php
index d813e944373..45b3056eac6 100644
--- a/app/code/Magento/Widget/Block/Adminhtml/Widget/Chooser.php
+++ b/app/code/Magento/Widget/Block/Adminhtml/Widget/Chooser.php
@@ -11,6 +11,9 @@
*/
namespace Magento\Widget\Block\Adminhtml\Widget;
+/**
+ * Chooser widget block.
+ */
class Chooser extends \Magento\Backend\Block\Template
{
/**
@@ -180,7 +183,7 @@ protected function _toHtml()
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/BuildWidget.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/BuildWidget.php
index d9ef20aa90e..0b9431f717e 100644
--- a/app/code/Magento/Widget/Controller/Adminhtml/Widget/BuildWidget.php
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/BuildWidget.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Widget\Controller\Adminhtml\Widget;
-class BuildWidget extends \Magento\Backend\App\Action
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
+
+class BuildWidget extends \Magento\Backend\App\Action implements HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Index.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Index.php
index 61e44fe00db..e7454faf925 100644
--- a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Index.php
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Widget\Controller\Adminhtml\Widget;
-class Index extends \Magento\Backend\App\Action
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
+
+class Index extends \Magento\Backend\App\Action implements HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Index.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Index.php
index 40ade57f6a9..50f3addaf7c 100644
--- a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Index.php
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Index.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
-class Index extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
+
+class Index extends \Magento\Widget\Controller\Adminhtml\Widget\Instance implements HttpGetActionInterface
{
/**
* Widget Instances Grid
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php
index b5d31dc10be..dc137365498 100644
--- a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php
@@ -6,7 +6,9 @@
*/
namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
-class Save extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
+
+class Save extends \Magento\Widget\Controller\Adminhtml\Widget\Instance implements HttpPostActionInterface
{
/**
* Save action
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/LoadOptions.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/LoadOptions.php
index 054019079eb..03d9d103113 100644
--- a/app/code/Magento/Widget/Controller/Adminhtml/Widget/LoadOptions.php
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/LoadOptions.php
@@ -6,9 +6,11 @@
*/
namespace Magento\Widget\Controller\Adminhtml\Widget;
+use Magento\Framework\App\Action\HttpGetActionInterface;
+use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\App\ObjectManager;
-class LoadOptions extends \Magento\Backend\App\Action
+class LoadOptions extends \Magento\Backend\App\Action implements HttpGetActionInterface, HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
diff --git a/app/code/Magento/Wishlist/Block/AbstractBlock.php b/app/code/Magento/Wishlist/Block/AbstractBlock.php
index 8b4a8df1bf9..bb8138fb87a 100644
--- a/app/code/Magento/Wishlist/Block/AbstractBlock.php
+++ b/app/code/Magento/Wishlist/Block/AbstractBlock.php
@@ -231,9 +231,21 @@ public function hasDescription($item)
* Retrieve formated Date
*
* @param string $date
+ * @deprecated
* @return string
*/
public function getFormatedDate($date)
+ {
+ return $this->getFormattedDate($date);
+ }
+
+ /**
+ * Retrieve formatted Date
+ *
+ * @param string $date
+ * @return string
+ */
+ public function getFormattedDate($date)
{
return $this->formatDate($date, \IntlDateFormatter::MEDIUM);
}
diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml
index 145fb94f356..c9a0c0cc0f8 100644
--- a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml
+++ b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml
@@ -13,10 +13,11 @@
-
-
+
+
+
diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDeletePersistedWishlistTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDeletePersistedWishlistTest.xml
index 0ae2b6af804..0001bd9d6db 100644
--- a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDeletePersistedWishlistTest.xml
+++ b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDeletePersistedWishlistTest.xml
@@ -13,12 +13,12 @@
+
-
+
-
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/images/logo-magento.png b/app/design/adminhtml/Magento/backend/Magento_Backend/web/images/logo-magento.png
index d9395c938cb..0cca183e08d 100644
Binary files a/app/design/adminhtml/Magento/backend/Magento_Backend/web/images/logo-magento.png and b/app/design/adminhtml/Magento/backend/Magento_Backend/web/images/logo-magento.png differ
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less
index c87b8f2ca5c..b3e4a91180b 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less
@@ -59,7 +59,11 @@
}
.abs-field-no-label {
+ /**
+ *@codingStandardsIgnoreStart
+ */
#mix-grid .return_length(@field-label-grid__column, @field-grid__columns, '+');
+ //@codingStandardsIgnoreEnd
margin-left: @_length;
}
@@ -166,6 +170,13 @@
.admin__control-text,
.admin__control-textarea {
width: 100%;
+ &.disabled {
+ background-color: #e9e9e9;
+ border-color: #adadad;
+ color: #303030;
+ cursor: not-allowed;
+ opacity: .5;
+ }
}
}
diff --git a/app/design/frontend/Magento/blank/web/images/logo.svg b/app/design/frontend/Magento/blank/web/images/logo.svg
index 013d6e7c5a1..0f29d4e3eef 100644
--- a/app/design/frontend/Magento/blank/web/images/logo.svg
+++ b/app/design/frontend/Magento/blank/web/images/logo.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
diff --git a/app/etc/di.xml b/app/etc/di.xml
index 8e050dec6eb..db979f9b763 100755
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -206,8 +206,6 @@
-
@@ -1695,4 +1693,32 @@
Magento\Framework\App\Config\ScopeConfigInterface::SCOPE_TYPE_DEFAULT
+
+
+
+
+ - CsrfRequestValidator
+ -
+ Magento\Framework\App\Request\HttpMethodValidator
+
+
+
+
+
+
+
+
+ - \Magento\Framework\App\Action\HttpOptionsActionInterface
+ - \Magento\Framework\App\Action\HttpGetActionInterface
+ - \Magento\Framework\App\Action\HttpHeadActionInterface
+ - \Magento\Framework\App\Action\HttpPostActionInterface
+ - \Magento\Framework\App\Action\HttpPutActionInterface
+ - \Magento\Framework\App\Action\HttpPatchActionInterface
+ - \Magento\Framework\App\Action\HttpDeleteActionInterface
+ - \Magento\Framework\App\Action\HttpConnectActionInterface
+ - \Magento\Framework\App\Action\HttpPropfindActionInterface
+ - \Magento\Framework\App\Action\HttpTraceActionInterface
+
+
+
diff --git a/composer.json b/composer.json
index e2a646275d9..3f8f0a033c8 100644
--- a/composer.json
+++ b/composer.json
@@ -221,6 +221,7 @@
"magento/module-tax": "*",
"magento/module-tax-import-export": "*",
"magento/module-theme": "*",
+ "magento/module-theme-graph-ql": "*",
"magento/module-translation": "*",
"magento/module-ui": "*",
"magento/module-ups": "*",
diff --git a/composer.lock b/composer.lock
index 2550f70f0be..1d101c8aaaf 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "18982aa4d36bcfd22cf073dfb578efdb",
+ "content-hash": "d6640ddfd342feceaec44c406c056f57",
"packages": [
{
"name": "braintree/braintree_php",
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
index f9442d8b649..1d37ea9a2fc 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
@@ -111,6 +111,9 @@ public function addDataProvider()
'option_with_value_node_that_starts_with_a_number' => [
array_merge($optionPayload, [AttributeOptionInterface::VALUE => '123_some_text'])
],
+ 'option_with_value_node_that_is_a_number' => [
+ array_merge($optionPayload, [AttributeOptionInterface::VALUE => '123'])
+ ],
];
}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php
index 8841fab7579..eff2e96f4b1 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php
@@ -225,7 +225,9 @@ public function testCategoryProducts()
}
short_description
sku
- small_image
+ small_image {
+ path
+ }
small_image_label
special_from_date
special_price
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryWithDescriptionDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryWithDescriptionDirectivesTest.php
new file mode 100644
index 00000000000..c115f7124c9
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryWithDescriptionDirectivesTest.php
@@ -0,0 +1,68 @@
+objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Catalog/_files/category.php
+ */
+ public function testHtmlDirectivesRendered()
+ {
+ $categoryId = 333;
+ $mediaFilePath = '/path/to/mediafile';
+ /** @var StoreManagerInterface $storeManager */
+ $storeManager = ObjectManager::getInstance()->get(StoreManagerInterface::class);
+ $storeBaseUrl = $storeManager->getStore()->getBaseUrl();
+
+ /* Remove index.php from base URL */
+ $storeBaseUrlParts = explode('/index.php', $storeBaseUrl);
+ $storeBaseUrl = $storeBaseUrlParts[0];
+
+ /** @var CategoryRepositoryInterface $categoryRepository */
+ $categoryRepository = ObjectManager::getInstance()->get(CategoryRepositoryInterface::class);
+ /** @var CategoryInterface $category */
+ $category = $categoryRepository->get($categoryId);
+ $category->setDescription('Test: {{media url="' . $mediaFilePath . '"}}');
+ $categoryRepository->save($category);
+
+ $query = <<graphQlQuery($query);
+
+ self::assertNotContains('media url', $response['category']['description']);
+ self::assertContains($storeBaseUrl, $response['category']['description']);
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php
new file mode 100644
index 00000000000..8da2702917a
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php
@@ -0,0 +1,63 @@
+objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php
+ */
+ public function testProductSmallImageUrlWithExistingImage()
+ {
+ $productSku = 'simple';
+ $query = <<graphQlQuery($query);
+
+ self::assertArrayHasKey('url', $response['products']['items'][0]['small_image']);
+ self::assertContains('magento_image.jpg', $response['products']['items'][0]['small_image']['url']);
+ self::assertTrue($this->checkImageExists($response['products']['items'][0]['small_image']['url']));
+ }
+
+ /**
+ * @param string $url
+ * @return bool
+ */
+ private function checkImageExists(string $url): bool
+ {
+ $connection = curl_init($url);
+ curl_setopt($connection, CURLOPT_HEADER, true);
+ curl_setopt($connection, CURLOPT_NOBODY, true);
+ curl_setopt($connection, CURLOPT_RETURNTRANSFER, 1);
+ curl_exec($connection);
+ $responseStatus = curl_getinfo($connection, CURLINFO_HTTP_CODE);
+
+ return $responseStatus === 200 ? true : false;
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php
index f1a79490b3d..99de6088b19 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchTest.php
@@ -381,84 +381,11 @@ public function testSearchWithFilterWithPageSizeEqualTotalCount()
}
QUERY;
$this->expectException(\Exception::class);
- $this->expectExceptionMessage('GraphQL response contains errors: currentPage value 1 specified is greater ' .
- 'than the number of pages available.');
+ $this->expectExceptionMessage('GraphQL response contains errors: currentPage value 2 specified is greater ' .
+ 'than the 1 page(s) available');
$this->graphQlQuery($query);
}
- /**
- * The query returns a total_count of 2 records; setting the pageSize = 1 and currentPage2
- * Expected result is to get the second product on the list on the second page
- *
- * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
- */
- public function testSearchWithFilterPageSizeLessThanCurrentPage()
- {
-
- $query
- = <<get(ProductRepositoryInterface::class);
- // when pagSize =1 and currentPage = 2, it should have simple2 on first page and simple1 on 2nd page
- // since sorting is done on price in the DESC order
- $product = $productRepository->get('simple1');
- $filteredProducts = [$product];
-
- $response = $this->graphQlQuery($query);
- $this->assertEquals(1, $response['products']['total_count']);
- $this->assertProductItems($filteredProducts, $response);
- }
-
/**
* Requesting for items that match a specific SKU or NAME within a certain price range sorted by Price in ASC order
*
@@ -549,12 +476,11 @@ public function testQueryProductsInCurrentPageSortedByPriceASC()
}
/**
- * Verify the items in the second page is correct after sorting their name in ASC order
+ * Verify the items is correct after sorting their name in ASC order
*
* @magentoApiDataFixture Magento/Catalog/_files/multiple_mixed_products_2.php
- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
- public function testFilterProductsInNextPageSortedByNameASC()
+ public function testQueryProductsSortedByNameASC()
{
$query
= <<get(ProductRepositoryInterface::class);
- $product = $productRepository->get('simple1');
- $filteredProducts = [$product];
+ $product = $productRepository->get('simple2');
$response = $this->graphQlQuery($query);
- $this->assertEquals(1, $response['products']['total_count']);
- $this->assertProductItems($filteredProducts, $response);
- $this->assertEquals(4, $response['products']['page_info']['page_size']);
+ $this->assertEquals(2, $response['products']['total_count']);
+ $this->assertEquals(['page_size' => 1, 'current_page' => 2], $response['products']['page_info']);
+ $this->assertEquals(
+ [['sku' => $product->getSku(), 'name' => $product->getName()]],
+ $response['products']['items']
+ );
}
/**
@@ -1132,8 +1043,8 @@ public function testQueryPageOutOfBoundException()
QUERY;
$this->expectException(\Exception::class);
- $this->expectExceptionMessage('GraphQL response contains errors: currentPage value 1 specified is greater ' .
- 'than the number of pages available.');
+ $this->expectExceptionMessage('GraphQL response contains errors: currentPage value 2 specified is greater ' .
+ 'than the 1 page(s) available.');
$this->graphQlQuery($query);
}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php
index 34cebde64d0..7c2cda3a455 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductViewTest.php
@@ -205,7 +205,9 @@ public function testQueryAllFieldsSimpleProduct()
}
short_description
sku
- small_image
+ small_image {
+ path
+ }
small_image_label
special_from_date
special_price
@@ -484,7 +486,7 @@ public function testQueryMediaGalleryEntryFieldsSimpleProduct()
QUERY;
$response = $this->graphQlQuery($query);
-
+
/**
* @var ProductRepositoryInterface $productRepository
*/
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php
new file mode 100644
index 00000000000..8e9bc4dfa28
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductWithDescriptionDirectivesTest.php
@@ -0,0 +1,65 @@
+objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+ * @magentoApiDataFixture Magento/Cms/_files/block.php
+ */
+ public function testHtmlDirectivesRendered()
+ {
+ $productSku = 'simple';
+ $cmsBlockId = 'fixture_block';
+ $assertionCmsBlockText = 'Fixture Block Title';
+
+ /** @var ProductRepositoryInterface $productRepository */
+ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
+ /** @var ProductInterface $product */
+ $product = $productRepository->get($productSku, false, null, true);
+ $product->setDescription('Test: {{block id="' . $cmsBlockId . '"}}');
+ $product->setShortDescription('Test: {{block id="' . $cmsBlockId . '"}}');
+ $productRepository->save($product);
+
+ $query = <<graphQlQuery($query);
+
+ self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['description']);
+ self::assertNotContains('{{block id', $response['products']['items'][0]['description']);
+ self::assertContains($assertionCmsBlockText, $response['products']['items'][0]['short_description']);
+ self::assertNotContains('{{block id', $response['products']['items'][0]['short_description']);
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php
new file mode 100644
index 00000000000..c39b32e4bfa
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/UrlRewritesTest.php
@@ -0,0 +1,149 @@
+graphQlQuery($query);
+
+ /** @var ProductRepositoryInterface $productRepository */
+ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
+ $product = $productRepository->get('virtual-product', false, null, true);
+
+ $urlFinder = ObjectManager::getInstance()->get(UrlFinderInterface::class);
+
+ $rewritesCollection = $urlFinder->findAllByData([UrlRewriteDTO::ENTITY_ID => $product->getId()]);
+
+ /* There should be only one rewrite */
+ /** @var UrlRewriteDTO $urlRewrite */
+ $urlRewrite = current($rewritesCollection);
+
+ $this->assertArrayHasKey('url_rewrites', $response['products']['items'][0]);
+ $this->assertCount(1, $response['products']['items'][0]['url_rewrites']);
+
+ $this->assertResponseFields(
+ $response['products']['items'][0]['url_rewrites'][0],
+ [
+ "url" => $urlRewrite->getRequestPath(),
+ "parameters" => $this->getUrlParameters($urlRewrite->getTargetPath())
+ ]
+ );
+ }
+
+ /**
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+ * @throws \Magento\Framework\Exception\NoSuchEntityException
+ */
+ public function testProductWithOneCategoryAssigned()
+ {
+ $productSku = 'simple';
+ $query
+ = <<graphQlQuery($query);
+
+ /** @var ProductRepositoryInterface $productRepository */
+ $productRepository = ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
+ $product = $productRepository->get('simple', false, null, true);
+
+ $urlFinder = ObjectManager::getInstance()->get(UrlFinderInterface::class);
+
+ $rewritesCollection = $urlFinder->findAllByData([UrlRewriteDTO::ENTITY_ID => $product->getId()]);
+ $rewritesCount = count($rewritesCollection);
+
+ $this->assertArrayHasKey('url_rewrites', $response['products']['items'][0]);
+ $this->assertCount($rewritesCount, $response['products']['items'][0]['url_rewrites']);
+
+ for ($i = 0; $i < $rewritesCount; $i++) {
+ $urlRewrite = $rewritesCollection[$i];
+ $this->assertResponseFields(
+ $response['products']['items'][0]['url_rewrites'][$i],
+ [
+ "url" => $urlRewrite->getRequestPath(),
+ "parameters" => $this->getUrlParameters($urlRewrite->getTargetPath())
+ ]
+ );
+ }
+ }
+
+ /**
+ * Parses target path and extracts parameters
+ *
+ * @param string $targetPath
+ * @return array
+ */
+ private function getUrlParameters(string $targetPath): array
+ {
+ $urlParameters = [];
+ $targetPathParts = explode('/', trim($targetPath, '/'));
+
+ for ($i = 3; ($i < sizeof($targetPathParts) - 1); $i += 2) {
+ $urlParameters[] = [
+ 'name' => $targetPathParts[$i],
+ 'value' => $targetPathParts[$i + 1]
+ ];
+ }
+
+ return $urlParameters;
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogInventory/ProductOnlyXLeftInStockTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogInventory/ProductOnlyXLeftInStockTest.php
index 4e49bb63e49..3969c758f12 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogInventory/ProductOnlyXLeftInStockTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/CatalogInventory/ProductOnlyXLeftInStockTest.php
@@ -16,7 +16,6 @@ class ProductOnlyXLeftInStockTest extends GraphQlAbstract
*/
public function testQueryProductOnlyXLeftInStockDisabled()
{
- $this->cleanCache();
$productSku = 'simple';
$query = <<customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class);
+ $this->accountManagement = Bootstrap::getObjectManager()->get(AccountManagementInterface::class);
+ $this->customerRegistry = Bootstrap::getObjectManager()->get(CustomerRegistry::class);
+ $this->customerAuthUpdate = Bootstrap::getObjectManager()->get(CustomerAuthUpdate::class);
+ $this->customerRepository = Bootstrap::getObjectManager()->get(CustomerRepositoryInterface::class);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ */
+ public function testGetAccountInformation()
+ {
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+
+ $query = <<graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));
+
+ $this->assertEquals('John', $response['customer']['firstname']);
+ $this->assertEquals('Smith', $response['customer']['lastname']);
+ $this->assertEquals($currentEmail, $response['customer']['email']);
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage The current customer isn't authorized.
+ */
+ public function testGetAccountInformationIfUserIsNotAuthorized()
+ {
+ $query = <<graphQlQuery($query);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ * @expectedException \Exception
+ * @expectedExceptionMessage The account is locked.
+ */
+ public function testGetAccountInformationIfCustomerIsLocked()
+ {
+ $this->lockCustomer(1);
+
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+
+ $query = <<graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ */
+ public function testUpdateAccountInformation()
+ {
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+
+ $newFirstname = 'Richard';
+ $newLastname = 'Rowe';
+ $newEmail = 'customer_updated@example.com';
+
+ $query = <<graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));
+
+ $this->assertEquals($newFirstname, $response['updateCustomer']['customer']['firstname']);
+ $this->assertEquals($newLastname, $response['updateCustomer']['customer']['lastname']);
+ $this->assertEquals($newEmail, $response['updateCustomer']['customer']['email']);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ * @expectedException \Exception
+ * @expectedExceptionMessage "input" value should be specified
+ */
+ public function testUpdateAccountInformationIfInputDataIsEmpty()
+ {
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+
+ $query = <<graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage The current customer isn't authorized.
+ */
+ public function testUpdateAccountInformationIfUserIsNotAuthorized()
+ {
+ $newFirstname = 'Richard';
+
+ $query = <<graphQlQuery($query);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ * @expectedException \Exception
+ * @expectedExceptionMessage The account is locked.
+ */
+ public function testUpdateAccountInformationIfCustomerIsLocked()
+ {
+ $this->lockCustomer(1);
+
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+ $newFirstname = 'Richard';
+
+ $query = <<graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ * @expectedException \Exception
+ * @expectedExceptionMessage For changing "email" you should provide current "password".
+ */
+ public function testUpdateEmailIfPasswordIsMissed()
+ {
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+ $newEmail = 'customer_updated@example.com';
+
+ $query = <<graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ * @expectedException \Exception
+ * @expectedExceptionMessage The password doesn't match this account. Verify the password and try again.
+ */
+ public function testUpdateEmailIfPasswordIsInvalid()
+ {
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+ $invalidPassword = 'invalid_password';
+ $newEmail = 'customer_updated@example.com';
+
+ $query = <<graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/two_customers.php
+ * @expectedException \Exception
+ * @expectedExceptionMessage A customer with the same email address already exists in an associated website.
+ */
+ public function testUpdateEmailIfEmailAlreadyExists()
+ {
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+ $existedEmail = 'customer_two@example.com';
+
+ $query = <<graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));
+ }
+
+ /**
+ * @param string $email
+ * @param string $password
+ * @return array
+ */
+ private function getCustomerAuthHeaders(string $email, string $password): array
+ {
+ $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password);
+ return ['Authorization' => 'Bearer ' . $customerToken];
+ }
+
+ /**
+ * @param int $customerId
+ * @return void
+ */
+ private function lockCustomer(int $customerId): void
+ {
+ $customerSecure = $this->customerRegistry->retrieveSecureData($customerId);
+ $customerSecure->setLockExpires('2030-12-31 00:00:00');
+ $this->customerAuthUpdate->saveAuth($customerId);
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CustomerAuthenticationTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AddressesTest.php
similarity index 84%
rename from dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CustomerAuthenticationTest.php
rename to dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AddressesTest.php
index 88ce7e91d94..9b7e3f28327 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CustomerAuthenticationTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/AddressesTest.php
@@ -14,16 +14,13 @@
use Magento\TestFramework\TestCase\GraphQlAbstract;
use Magento\Integration\Api\CustomerTokenServiceInterface;
-class CustomerAuthenticationTest extends GraphQlAbstract
+class AddressesTest extends GraphQlAbstract
{
/**
- * Verify customers with valid credentials with a customer bearer token
- *
* @magentoApiDataFixture Magento/Customer/_files/customer.php
* @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php
- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
- public function testRegisteredCustomerWithValidCredentials()
+ public function testGetCustomerWithAddresses()
{
$query
= <<assertCustomerAddressesFields($customer, $response);
}
- /**
- * Verify customer with valid credentials but without the bearer token
- *
- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
- */
- public function testCustomerWithValidCredentialsWithoutToken()
- {
- $query
- = <<expectException(\Exception::class);
- $this->expectExceptionMessage('GraphQL response contains errors: Current customer' . ' ' .
- 'does not have access to the resource "customer"');
- $this->graphQlQuery($query);
- }
-
/**
* Verify the all the whitelisted fields for a Customer Object
*
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CustomerChangePasswordTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CustomerChangePasswordTest.php
new file mode 100644
index 00000000000..f2451818152
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CustomerChangePasswordTest.php
@@ -0,0 +1,141 @@
+customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class);
+ $this->accountManagement = Bootstrap::getObjectManager()->get(AccountManagementInterface::class);
+ $this->customerRegistry = Bootstrap::getObjectManager()->get(CustomerRegistry::class);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ */
+ public function testChangePassword()
+ {
+ $customerEmail = 'customer@example.com';
+ $oldCustomerPassword = 'password';
+ $newCustomerPassword = 'anotherPassword1';
+
+ $query = $this->getChangePassQuery($oldCustomerPassword, $newCustomerPassword);
+ $headerMap = $this->getCustomerAuthHeaders($customerEmail, $oldCustomerPassword);
+
+ $response = $this->graphQlQuery($query, [], '', $headerMap);
+ $this->assertEquals($customerEmail, $response['changeCustomerPassword']['email']);
+
+ try {
+ // registry contains the old password hash so needs to be reset
+ $this->customerRegistry->removeByEmail($customerEmail);
+ $this->accountManagement->authenticate($customerEmail, $newCustomerPassword);
+ } catch (LocalizedException $e) {
+ $this->fail('Password was not changed: ' . $e->getMessage());
+ }
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage The current customer isn't authorized.
+ */
+ public function testChangePasswordIfUserIsNotAuthorizedTest()
+ {
+ $query = $this->getChangePassQuery('currentpassword', 'newpassword');
+ $this->graphQlQuery($query);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ */
+ public function testChangeWeakPassword()
+ {
+ $this->markTestIncomplete('https://github.com/magento/graphql-ce/issues/190');
+ $customerEmail = 'customer@example.com';
+ $oldCustomerPassword = 'password';
+ $newCustomerPassword = 'weakpass';
+
+ $query = $this->getChangePassQuery($oldCustomerPassword, $newCustomerPassword);
+ $headerMap = $this->getCustomerAuthHeaders($customerEmail, $oldCustomerPassword);
+
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessageRegExp('/Minimum of different classes of characters in password is.*/');
+
+ $this->graphQlQuery($query, [], '', $headerMap);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ * @expectedException \Exception
+ * @expectedExceptionMessage The password doesn't match this account. Verify the password and try again.
+ */
+ public function testChangePasswordIfPasswordIsInvalid()
+ {
+ $customerEmail = 'customer@example.com';
+ $oldCustomerPassword = 'password';
+ $newCustomerPassword = 'anotherPassword1';
+ $incorrectPassword = 'password-incorrect';
+
+ $query = $this->getChangePassQuery($incorrectPassword, $newCustomerPassword);
+
+ $headerMap = $this->getCustomerAuthHeaders($customerEmail, $oldCustomerPassword);
+ $this->graphQlQuery($query, [], '', $headerMap);
+ }
+
+ private function getChangePassQuery($currentPassword, $newPassword)
+ {
+ $query = <<customerTokenService->createCustomerAccessToken($email, $password);
+ return ['Authorization' => 'Bearer ' . $customerToken];
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GenerateCustomerTokenTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GenerateCustomerTokenTest.php
new file mode 100644
index 00000000000..ae28e23a28b
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/GenerateCustomerTokenTest.php
@@ -0,0 +1,71 @@
+graphQlQuery($mutation);
+ $this->assertArrayHasKey('generateCustomerToken', $response);
+ $this->assertInternalType('array', $response['generateCustomerToken']);
+ }
+
+ /**
+ * Verify customer with invalid credentials
+ */
+ public function testGenerateCustomerTokenWithInvalidCredentials()
+ {
+ $userName = 'customer@example.com';
+ $password = 'bad-password';
+
+ $mutation
+ = <<expectException(\Exception::class);
+ $this->expectExceptionMessage('GraphQL response contains errors: The account sign-in' . ' ' .
+ 'was incorrect or your account is disabled temporarily. Please wait and try again later.');
+ $this->graphQlQuery($mutation);
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php
new file mode 100644
index 00000000000..415a81f8cf4
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/RevokeCustomerTokenTest.php
@@ -0,0 +1,54 @@
+get(CustomerTokenServiceInterface::class);
+ $customerToken = $customerTokenService->createCustomerAccessToken($userName, $password);
+
+ $headerMap = ['Authorization' => 'Bearer ' . $customerToken];
+ $response = $this->graphQlQuery($query, [], '', $headerMap);
+ $this->assertTrue($response['revokeCustomerToken']);
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage The current customer isn't authorized.
+ */
+ public function testRevokeCustomerTokenForGuestCustomer()
+ {
+ $query = <<graphQlQuery($query, [], '');
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/SubscriptionStatusTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/SubscriptionStatusTest.php
new file mode 100644
index 00000000000..191ea1ae6b8
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/SubscriptionStatusTest.php
@@ -0,0 +1,134 @@
+customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class);
+ $this->subscriberFactory = Bootstrap::getObjectManager()->get(SubscriberFactory::class);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ */
+ public function testGetSubscriptionStatusTest()
+ {
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+
+ $query = <<graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));
+ $this->assertFalse($response['customer']['is_subscribed']);
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage The current customer isn't authorized.
+ */
+ public function testGetSubscriptionStatusIfUserIsNotAuthorizedTest()
+ {
+ $query = <<graphQlQuery($query);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ */
+ public function testChangeSubscriptionStatusTest()
+ {
+ $currentEmail = 'customer@example.com';
+ $currentPassword = 'password';
+
+ $query = <<graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword));
+ $this->assertTrue($response['updateCustomer']['customer']['is_subscribed']);
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage The current customer isn't authorized.
+ */
+ public function testChangeSubscriptionStatuIfUserIsNotAuthorizedTest()
+ {
+ $query = <<graphQlQuery($query);
+ }
+
+ /**
+ * @param string $email
+ * @param string $password
+ * @return array
+ */
+ private function getCustomerAuthHeaders(string $email, string $password): array
+ {
+ $customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password);
+ return ['Authorization' => 'Bearer ' . $customerToken];
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ $this->subscriberFactory->create()->loadByCustomerId(1)->delete();
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/CouponTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/CouponTest.php
new file mode 100644
index 00000000000..1f8ad06a9f8
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/CouponTest.php
@@ -0,0 +1,225 @@
+quoteResource = $objectManager->create(QuoteResource::class);
+ $this->quote = $objectManager->create(Quote::class);
+ $this->quoteIdToMaskedId = $objectManager->create(QuoteIdToMaskedQuoteIdInterface::class);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
+ * @magentoApiDataFixture Magento/SalesRule/_files/coupon_code_with_wildcard.php
+ */
+ public function testApplyCouponToGuestCartWithItems()
+ {
+ $couponCode = '2?ds5!2d';
+
+ $this->quoteResource->load(
+ $this->quote,
+ 'test_order_with_simple_product_without_address',
+ 'reserved_order_id'
+ );
+ $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId());
+ $query = $this->prepareAddCouponRequestQuery($maskedQuoteId, $couponCode);
+ $response = $this->graphQlQuery($query);
+
+ self::assertArrayHasKey("applyCouponToCart", $response);
+ self::assertEquals($couponCode, $response['applyCouponToCart']['cart']['applied_coupon']['code']);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
+ * @magentoApiDataFixture Magento/SalesRule/_files/coupon_code_with_wildcard.php
+ */
+ public function testApplyCouponTwice()
+ {
+ $couponCode = '2?ds5!2d';
+
+ $this->quoteResource->load(
+ $this->quote,
+ 'test_order_with_simple_product_without_address',
+ 'reserved_order_id'
+ );
+ $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId());
+ $query = $this->prepareAddCouponRequestQuery($maskedQuoteId, $couponCode);
+ $response = $this->graphQlQuery($query);
+
+ self::assertArrayHasKey("applyCouponToCart", $response);
+ self::assertEquals($couponCode, $response['applyCouponToCart']['cart']['applied_coupon']['code']);
+
+ self::expectExceptionMessage('A coupon is already applied to the cart. Please remove it to apply another');
+ $this->graphQlQuery($query);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
+ * @magentoApiDataFixture Magento/SalesRule/_files/coupon_code_with_wildcard.php
+ */
+ public function testApplyCouponToCartWithNoItems()
+ {
+ $this->markTestIncomplete('https://github.com/magento/graphql-ce/issues/191');
+ $couponCode = '2?ds5!2d';
+
+ $this->quoteResource->load($this->quote, 'test_order_1', 'reserved_order_id');
+ $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId());
+ $query = $this->prepareAddCouponRequestQuery($maskedQuoteId, $couponCode);
+
+ self::expectExceptionMessageRegExp('/Cart doesn\'t contain products/');
+ $this->graphQlQuery($query);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
+ * @magentoApiDataFixture Magento/SalesRule/_files/coupon_code_with_wildcard.php
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ */
+ public function testGuestCustomerAttemptToChangeCustomerCart()
+ {
+ $couponCode = '2?ds5!2d';
+
+ $this->quoteResource->load(
+ $this->quote,
+ 'test_order_with_simple_product_without_address',
+ 'reserved_order_id'
+ );
+ $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId());
+ $this->quote->setCustomerId(1);
+ $this->quoteResource->save($this->quote);
+ $query = $this->prepareAddCouponRequestQuery($maskedQuoteId, $couponCode);
+
+ self::expectExceptionMessage('The current user cannot perform operations on cart "' . $maskedQuoteId . '"');
+ $this->graphQlQuery($query);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
+ * @magentoApiDataFixture Magento/SalesRule/_files/coupon_code_with_wildcard.php
+ */
+ public function testRemoveCoupon()
+ {
+ $couponCode = '2?ds5!2d';
+
+ /* Apply coupon to the quote */
+ $this->quoteResource->load(
+ $this->quote,
+ 'test_order_with_simple_product_without_address',
+ 'reserved_order_id'
+ );
+ $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId());
+ $this->quoteResource->load(
+ $this->quote,
+ 'test_order_with_simple_product_without_address',
+ 'reserved_order_id'
+ );
+ $query = $this->prepareAddCouponRequestQuery($maskedQuoteId, $couponCode);
+ $this->graphQlQuery($query);
+
+ /* Remove coupon from quote */
+ $query = $this->prepareRemoveCouponRequestQuery($maskedQuoteId);
+ $response = $this->graphQlQuery($query);
+
+ self::assertArrayHasKey('removeCouponFromCart', $response);
+ self::assertSame('', $response['removeCouponFromCart']['cart']['applied_coupon']['code']);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
+ * @magentoApiDataFixture Magento/SalesRule/_files/coupon_code_with_wildcard.php
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ */
+ public function testRemoveCouponFromCustomerCartByGuest()
+ {
+ $this->quoteResource->load(
+ $this->quote,
+ 'test_order_with_simple_product_without_address',
+ 'reserved_order_id'
+ );
+ $maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId());
+ $this->quoteResource->load(
+ $this->quote,
+ 'test_order_with_simple_product_without_address',
+ 'reserved_order_id'
+ );
+ $this->quote->setCustomerId(1);
+ $this->quoteResource->save($this->quote);
+ $query = $this->prepareRemoveCouponRequestQuery($maskedQuoteId);
+
+ self::expectExceptionMessage('The current user cannot perform operations on cart "' . $maskedQuoteId . '"');
+ $this->graphQlQuery($query);
+ }
+
+ /**
+ * @param string $maskedQuoteId
+ * @param string $couponCode
+ * @return string
+ */
+ private function prepareAddCouponRequestQuery(string $maskedQuoteId, string $couponCode): string
+ {
+ return <<markTestIncomplete('https://github.com/magento/graphql-ce/issues/167');
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
}
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php
index 0bd24ee7bc8..c70b1631e85 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/UrlRewrite/UrlResolverTest.php
@@ -12,6 +12,9 @@
use Magento\TestFramework\ObjectManager;
use Magento\TestFramework\TestCase\GraphQlAbstract;
use Magento\UrlRewrite\Model\UrlFinderInterface;
+use Magento\Cms\Helper\Page as PageHelper;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Framework\App\Config\ScopeConfigInterface;
/**
* Test the GraphQL endpoint's URLResolver query to verify canonical URL's are correctly returned.
@@ -321,6 +324,20 @@ public function testCategoryUrlWithLeadingSlash()
*/
public function testResolveSlash()
{
+ /** @var \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfigInterface */
+ $scopeConfigInterface = $this->objectManager->get(ScopeConfigInterface::class);
+ $homePageIdentifier = $scopeConfigInterface->getValue(
+ PageHelper::XML_PATH_HOME_PAGE,
+ ScopeInterface::SCOPE_STORE
+ );
+ /** @var \Magento\Cms\Model\Page $page */
+ $page = $this->objectManager->get(\Magento\Cms\Model\Page::class);
+ $page->load($homePageIdentifier);
+ $homePageId = $page->getId();
+ /** @var \Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator $urlPathGenerator */
+ $urlPathGenerator = $this->objectManager->get(\Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator::class);
+ /** @param \Magento\Cms\Api\Data\PageInterface $page */
+ $targetPath = $urlPathGenerator->getCanonicalUrlPath($page);
$query
= <<graphQlQuery($query);
-
$this->assertArrayHasKey('urlResolver', $response);
- $this->assertEquals(2, $response['urlResolver']['id']);
- $this->assertEquals('cms/page/view/page_id/2', $response['urlResolver']['canonical_url']);
+ $this->assertEquals($homePageId, $response['urlResolver']['id']);
+ $this->assertEquals($targetPath, $response['urlResolver']['canonical_url']);
$this->assertEquals('CMS_PAGE', $response['urlResolver']['type']);
}
}
diff --git a/dev/tests/functional/lib/Magento/Mtf/Constraint/AbstractAssertForm.php b/dev/tests/functional/lib/Magento/Mtf/Constraint/AbstractAssertForm.php
index eb04450d526..61e5b764930 100644
--- a/dev/tests/functional/lib/Magento/Mtf/Constraint/AbstractAssertForm.php
+++ b/dev/tests/functional/lib/Magento/Mtf/Constraint/AbstractAssertForm.php
@@ -53,7 +53,7 @@ protected function verifyData(array $fixtureData, array $formData, $isStrict = f
}
$formValue = isset($formData[$key]) ? $formData[$key] : null;
if (is_numeric($formValue)) {
- $formValue = floatval($formValue);
+ $formValue = (float)$formValue;
}
if (null === $formValue) {
@@ -118,6 +118,7 @@ protected function sortData(array $data)
/**
* Sort multidimensional array by paths.
+ *
* Pattern path: key/subKey::sortKey.
* Example:
* $data = [
@@ -150,7 +151,6 @@ protected function sortData(array $data)
*
* @param array $data
* @param string $path
- * @param string $path
* @return array
* @throws \Exception
*
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php
index 3738f51ef6c..01d8401b22f 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php
@@ -6,6 +6,7 @@
namespace Magento\Backend\Test\Handler\Ui;
+use Magento\Backend\Test\Page\AdminAuthLogin;
use Magento\Mtf\Factory\Factory;
use Magento\Mtf\Fixture\FixtureInterface;
use Magento\Mtf\Handler\Ui;
@@ -29,10 +30,15 @@ public function persist(FixtureInterface $fixture = null)
$fixture = Factory::getFixtureFactory()->getMagentoBackendAdminSuperAdmin();
}
+ /** @var AdminAuthLogin $loginPage */
$loginPage = Factory::getPageFactory()->getAdminAuthLogin();
$loginForm = $loginPage->getLoginBlock();
-
$adminHeaderPanel = $loginPage->getHeaderBlock();
+ if (!$loginForm->isVisible() && !$adminHeaderPanel->isVisible()) {
+ //We are currently not in the admin area.
+ $loginPage->open();
+ }
+
if (!$adminHeaderPanel || !$adminHeaderPanel->isVisible()) {
$loginPage->open();
if ($adminHeaderPanel->isVisible()) {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php
index 9f05a4ade8a..dcc8cce9700 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php
@@ -231,7 +231,7 @@ protected function getFieldData(SimpleElement $option)
return [
'options' => [
[
- 'price' => floatval($price),
+ 'price' => (float)$price,
'max_characters' => $maxCharacters,
],
]
@@ -262,7 +262,7 @@ protected function getFileData(SimpleElement $option)
return [
'options' => [
[
- 'price' => floatval($price),
+ 'price' => (float)$price,
'file_extension' => $this->getOptionNotice($option, 1),
'image_size_x' => preg_replace('/[^0-9]/', '', $this->getOptionNotice($option, 2)),
'image_size_y' => preg_replace('/[^0-9]/', '', $this->getOptionNotice($option, 3)),
@@ -344,7 +344,7 @@ protected function getDateData(SimpleElement $option)
return [
'options' => [
[
- 'price' => floatval($price),
+ 'price' => (float)$price,
],
]
];
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php
index 5e871bf6d97..707a62a4460 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.php
@@ -10,6 +10,7 @@
use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew;
use Magento\Mtf\Fixture\FixtureFactory;
use Magento\Mtf\TestCase\Injectable;
+use Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Section\Downloadable;
/**
* Test Creation for ProductTypeSwitchingOnCreation
@@ -75,18 +76,49 @@ public function __inject(
*
* @param string $createProduct
* @param string $product
+ * @param string $actionName
* @return array
*/
- public function test($createProduct, $product)
+ public function test(string $createProduct, string $product, string $actionName = null): array
{
// Steps
list($fixture, $dataset) = explode('::', $product);
$product = $this->fixtureFactory->createByCode($fixture, ['dataset' => $dataset]);
$this->catalogProductIndex->open();
$this->catalogProductIndex->getGridPageActionBlock()->addProduct($createProduct);
+ if ($actionName) {
+ $this->performAction($actionName);
+ }
$this->catalogProductNew->getProductForm()->fill($product);
$this->catalogProductNew->getFormPageActions()->save($product);
return ['product' => $product];
}
+
+ /**
+ * Perform action.
+ *
+ * @param string $actionName
+ * @return void
+ */
+ private function performAction(string $actionName): void
+ {
+ if (method_exists(__CLASS__, $actionName)) {
+ $this->$actionName();
+ }
+ }
+
+ /**
+ * Clear downloadable product data.
+ *
+ * @return void
+ */
+ private function clearDownloadableData(): void
+ {
+ $this->catalogProductNew->getProductForm()->openSection('downloadable_information');
+ /** @var Downloadable $downloadableInfoTab */
+ $downloadableInfoTab = $this->catalogProductNew->getProductForm()->getSection('downloadable_information');
+ $downloadableInfoTab->getDownloadableBlock('Links')->clearDownloadableData();
+ $downloadableInfoTab->setIsDownloadable('No');
+ }
}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml
index f45fbc96a73..460cc29b183 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnCreationTest.xml
@@ -76,7 +76,8 @@
downloadable
configurableProduct::not_virtual_for_type_switching
- to_maintain:yes
+ clearDownloadableData
+ MSI-1624
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleForm.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleForm.php
index 7db32337b99..17739f5524e 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleForm.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleForm.php
@@ -42,10 +42,10 @@ public function processAssert(
$fixtureData = $catalogPriceRule->getData();
//convert discount_amount to float to compare
if (isset($formData['discount_amount'])) {
- $formData['discount_amount'] = floatval($formData['discount_amount']);
+ $formData['discount_amount'] = (float)$formData['discount_amount'];
}
if (isset($fixtureData['discount_amount'])) {
- $fixtureData['discount_amount'] = floatval($fixtureData['discount_amount']);
+ $fixtureData['discount_amount'] = (float)$fixtureData['discount_amount'];
}
$diff = $this->verifyData($formData, $fixtureData);
\PHPUnit\Framework\Assert::assertTrue(
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml
index 387e6418ee5..2cb0e287404 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.xml
@@ -125,7 +125,6 @@
- MAGETWO-66737: Magento\Checkout\Test\TestCase\OnePageCheckoutTest with OnePageCheckoutTestVariation3 and 4 is not stable
test_type:acceptance_test, test_type:extended_acceptance_test, severity:S0
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml
index 22d29eae165..1a7adcd531c 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsPage.xml
@@ -7,6 +7,6 @@
-->
-
+
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Downloadable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Downloadable.php
index ebc19eec9ad..d78a2d94e76 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Downloadable.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Section/Downloadable.php
@@ -104,4 +104,21 @@ public function setFieldsData(array $fields, SimpleElement $element = null)
return $this;
}
+
+ /**
+ * Set "Is this downloadable Product?" value.
+ *
+ * @param string $downloadable
+ * @param SimpleElement|null $element
+ * @return void
+ */
+ public function setIsDownloadable(string $downloadable = 'Yes', SimpleElement $element = null): void
+ {
+ $context = $element ?: $this->_rootElement;
+ $isDownloadable = $context->find($this->isDownloadableProduct);
+ $value = 'Yes' == $downloadable ? '1' : '0';
+ if ($isDownloadable->isVisible() && $isDownloadable->getAttribute('value') != $value) {
+ $isDownloadable->click();
+ }
+ }
}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableDuplicateForm.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableDuplicateForm.php
index e5d97e1511e..2033189214e 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableDuplicateForm.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableDuplicateForm.php
@@ -32,11 +32,7 @@ protected function sortDownloadableArray(array $fields)
usort(
$fields,
function ($row1, $row2) {
- if ($row1['sort_order'] == $row2['sort_order']) {
- return 0;
- }
-
- return ($row1['sort_order'] < $row2['sort_order']) ? -1 : 1;
+ return $row1['sort_order'] <=> $row2['sort_order'];
}
);
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/DownloadableProduct/Webapi.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/DownloadableProduct/Webapi.php
index 434c78e55c6..d14d6754b12 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/DownloadableProduct/Webapi.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/DownloadableProduct/Webapi.php
@@ -148,7 +148,7 @@ protected function prepareLinkData(array $link)
'title' => $link['title'],
'sort_order' => isset($link['sort_order']) ? $link['sort_order'] : 0,
'is_shareable' => $link['is_shareable'],
- 'price' => floatval($link['price']),
+ 'price' => (float)$link['price'],
'number_of_downloads' => isset($link['number_of_downloads']) ? $link['number_of_downloads'] : 0,
'link_type' => $link['type'],
'link_url' => isset($link['link_url']) ? $link['link_url'] : null,
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertSalesReportIntervalResult.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertSalesReportIntervalResult.php
index 745450aa2c0..1236a86e160 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertSalesReportIntervalResult.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertSalesReportIntervalResult.php
@@ -52,7 +52,7 @@ protected function prepareSalesResult($salesResult)
{
$data = [];
foreach ($salesResult as $key => $result) {
- $data[$key] = floatval($result);
+ $data[$key] = (float)$result;
}
return $data;
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertSalesReportTotalResult.php b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertSalesReportTotalResult.php
index 5f435e48229..423ca6dafbd 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertSalesReportTotalResult.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Constraint/AssertSalesReportTotalResult.php
@@ -52,7 +52,7 @@ protected function prepareSalesResult($salesResult)
{
$data = [];
foreach ($salesResult as $key => $result) {
- $data[$key] = floatval($result);
+ $data[$key] = (float)$result;
}
return $data;
diff --git a/dev/tests/functional/utils/log.php b/dev/tests/functional/utils/log.php
index b6c19458b10..68a68d4bad6 100644
--- a/dev/tests/functional/utils/log.php
+++ b/dev/tests/functional/utils/log.php
@@ -4,11 +4,16 @@
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
if (!isset($_GET['name'])) {
- throw new \InvalidArgumentException('The name of log file is required for getting logs.');
+ throw new \InvalidArgumentException(
+ 'The name of log file is required for getting logs.'
+ );
}
-
$name = urldecode($_GET['name']);
-$file = file_get_contents('../../../../var/log/' . $name);
+if (preg_match('/\.\.(\\\|\/)/', $name)) {
+ throw new \InvalidArgumentException('Invalid log file name');
+}
-echo serialize($file);
+echo serialize(file_get_contents('../../../../var/log' .'/' .$name));
diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php
index 4fec36633c9..1bfc928f291 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/Application.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php
@@ -498,6 +498,7 @@ public function install($cleanup)
$this->_ensureDirExists($this->_initParams[$dirs][DirectoryList::VAR_DIR][DirectoryList::PATH]);
$this->copyAppConfigFiles();
+ $this->copyGlobalConfigFile();
$installParams = $this->getInstallCliParams();
@@ -557,6 +558,17 @@ private function copyAppConfigFiles()
}
}
}
+
+ /**
+ * Copies global configuration file from the tests folder (see TESTS_GLOBAL_CONFIG_FILE)
+ *
+ * @return void
+ */
+ private function copyGlobalConfigFile()
+ {
+ $targetFile = $this->_configDir . '/config.local.php';
+ copy($this->globalConfigFile, $targetFile);
+ }
/**
* Gets a list of CLI params for installation
diff --git a/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractBackendController.php b/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractBackendController.php
index 543bac2c6b5..b2e0b57bae7 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractBackendController.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractBackendController.php
@@ -5,10 +5,12 @@
*/
namespace Magento\TestFramework\TestCase;
+use Magento\Framework\App\Request\Http as HttpRequest;
+
/**
- * A parent class for backend controllers - contains directives for admin user creation and authentication
+ * A parent class for backend controllers - contains directives for admin user creation and authentication.
+ *
* @SuppressWarnings(PHPMD.NumberOfChildren)
- * @SuppressWarnings(PHPMD.numberOfChildren)
*/
abstract class AbstractBackendController extends \Magento\TestFramework\TestCase\AbstractController
{
@@ -36,6 +38,16 @@ abstract class AbstractBackendController extends \Magento\TestFramework\TestCase
*/
protected $uri = null;
+ /**
+ * @var string|null
+ */
+ protected $httpMethod;
+
+ /**
+ * @inheritDoc
+ *
+ * @throws \Magento\Framework\Exception\AuthenticationException
+ */
protected function setUp()
{
parent::setUp();
@@ -62,6 +74,9 @@ protected function _getAdminCredentials()
];
}
+ /**
+ * @inheritDoc
+ */
protected function tearDown()
{
$this->_auth->getAuthStorage()->destroy(['send_expire_cookie' => false]);
@@ -86,21 +101,33 @@ public function assertSessionMessages(
parent::assertSessionMessages($constraint, $messageType, $messageManagerClass);
}
+ /**
+ * Test ACL configuration for action working.
+ */
public function testAclHasAccess()
{
if ($this->uri === null) {
$this->markTestIncomplete('AclHasAccess test is not complete');
}
+ if ($this->httpMethod) {
+ $this->getRequest()->setMethod($this->httpMethod);
+ }
$this->dispatch($this->uri);
$this->assertNotSame(403, $this->getResponse()->getHttpResponseCode());
$this->assertNotSame(404, $this->getResponse()->getHttpResponseCode());
}
+ /**
+ * Test ACL actually denying access.
+ */
public function testAclNoAccess()
{
if ($this->resource === null) {
$this->markTestIncomplete('Acl test is not complete');
}
+ if ($this->httpMethod) {
+ $this->getRequest()->setMethod($this->httpMethod);
+ }
$this->_objectManager->get(\Magento\Framework\Acl\Builder::class)
->getAcl()
->deny(null, $this->resource);
diff --git a/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractController.php b/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractController.php
index 1bf6d471fc4..feb9eca0793 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractController.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractController.php
@@ -10,10 +10,12 @@
namespace Magento\TestFramework\TestCase;
use Magento\Framework\Data\Form\FormKey;
+use Magento\Framework\Message\MessageInterface;
use Magento\Framework\Stdlib\CookieManagerInterface;
use Magento\Framework\View\Element\Message\InterpretationStrategyInterface;
use Magento\Theme\Controller\Result\MessagePlugin;
use Magento\Framework\App\Request\Http as HttpRequest;
+use Magento\Framework\App\Response\Http as HttpResponse;
/**
* @SuppressWarnings(PHPMD.NumberOfChildren)
@@ -70,6 +72,9 @@ protected function setUp()
$this->_objectManager->removeSharedInstance(\Magento\Framework\App\RequestInterface::class);
}
+ /**
+ * @inheritDoc
+ */
protected function tearDown()
{
$this->_request = null;
@@ -114,7 +119,7 @@ public function dispatch($uri)
/**
* Request getter
*
- * @return \Magento\Framework\App\RequestInterface
+ * @return \Magento\Framework\App\RequestInterface|HttpRequest
*/
public function getRequest()
{
@@ -127,7 +132,7 @@ public function getRequest()
/**
* Response getter
*
- * @return \Magento\Framework\App\ResponseInterface
+ * @return \Magento\Framework\App\ResponseInterface|HttpResponse
*/
public function getResponse()
{
@@ -212,13 +217,21 @@ public function assertSessionMessages(
$messageManagerClass = \Magento\Framework\Message\Manager::class
) {
$this->_assertSessionErrors = false;
-
+ /** @var MessageInterface[]|string[] $messageObjects */
$messages = $this->getMessages($messageType, $messageManagerClass);
+ /** @var string[] $messages */
+ $messagesFiltered = array_map(
+ function ($message) {
+ /** @var MessageInterface|string $message */
+ return ($message instanceof MessageInterface) ? $message->toString() : $message;
+ },
+ $messages
+ );
$this->assertThat(
- $messages,
+ $messagesFiltered,
$constraint,
- 'Session messages do not meet expectations ' . var_export($messages, true)
+ 'Session messages do not meet expectations ' . var_export($messagesFiltered, true)
);
}
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/IndexTest.php b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/IndexTest.php
index 219fde6e370..d5a48b96081 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/IndexTest.php
@@ -5,6 +5,8 @@
*/
namespace Magento\Backend\Controller\Adminhtml;
+use Magento\Framework\App\Request\Http as HttpRequest;
+
/**
* @magentoAppArea adminhtml
* @magentoDbIsolation enabled
@@ -45,6 +47,7 @@ public function testLoggedIndexAction()
public function testGlobalSearchAction()
{
$this->getRequest()->setParam('isAjax', 'true');
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue('query', 'dummy');
$this->dispatch('backend/admin/index/globalSearch');
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/UrlRewriteTest.php b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/UrlRewriteTest.php
index 1185ae9727e..0d48fc8b0f5 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/UrlRewriteTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/UrlRewriteTest.php
@@ -5,6 +5,8 @@
*/
namespace Magento\Backend\Controller\Adminhtml;
+use Magento\Framework\App\Request\Http as HttpRequest;
+
/**
* @magentoAppArea adminhtml
*/
@@ -20,6 +22,7 @@ public function testSaveActionCmsPage()
$page = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Cms\Model\Page::class);
$page->load('page_design_blank', 'identifier');
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue(
[
'description' => 'Some URL rewrite description',
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php
index 11f49464bbd..a6d03fcc200 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php
@@ -5,6 +5,8 @@
*/
namespace Magento\Catalog\Controller\Adminhtml;
+use Magento\Framework\App\Request\Http as HttpRequest;
+
/**
* @magentoAppArea adminhtml
*/
@@ -27,6 +29,7 @@ public function testSaveAction($inputData, $defaultAttributes, $attributesSaved
$store->load('fixturestore', 'code');
$storeId = $store->getId();
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($inputData);
$this->getRequest()->setParam('store', $storeId);
$this->getRequest()->setParam('id', 2);
@@ -75,6 +78,7 @@ public function testSaveAction($inputData, $defaultAttributes, $attributesSaved
*/
public function testSaveActionFromProductCreationPage($postData)
{
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
$this->dispatch('backend/catalog/category/save');
@@ -123,6 +127,9 @@ public static function categoryCreatedFromProductCreationPageDataProvider()
return [[$postData], [$postData + ['return_session_messages_only' => 1]]];
}
+ /**
+ * Test SuggestCategories finds any categories.
+ */
public function testSuggestCategoriesActionDefaultCategoryFound()
{
$this->getRequest()->setParam('label_part', 'Default');
@@ -133,6 +140,9 @@ public function testSuggestCategoriesActionDefaultCategoryFound()
);
}
+ /**
+ * Test SuggestCategories properly processes search by label.
+ */
public function testSuggestCategoriesActionNoSuggestions()
{
$this->getRequest()->setParam('label_part', strrev('Default'));
@@ -322,8 +332,12 @@ public function saveActionDataProvider()
];
}
+ /**
+ * Test validation.
+ */
public function testSaveActionCategoryWithDangerRequest()
{
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue(
[
'general' => [
@@ -374,7 +388,8 @@ public function testMoveAction($parentId, $childId, $childUrlKey, $grandChildId,
}
$this->getRequest()
->setPostValue('id', $grandChildId)
- ->setPostValue('pid', $parentId);
+ ->setPostValue('pid', $parentId)
+ ->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/catalog/category/move');
$jsonResponse = json_decode($this->getResponse()->getBody());
$this->assertNotNull($jsonResponse);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php
index cea49d940cb..a2967878402 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Action/AttributeTest.php
@@ -5,6 +5,8 @@
*/
namespace Magento\Catalog\Controller\Adminhtml\Product\Action;
+use Magento\Framework\App\Request\Http as HttpRequest;
+
/**
* @magentoAppArea adminhtml
*/
@@ -23,6 +25,7 @@ public function testSaveActionRedirectsSuccessfully()
/** @var $session \Magento\Backend\Model\Session */
$session = $objectManager->get(\Magento\Backend\Model\Session::class);
$session->setProductIds([1]);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/catalog/product_action_attribute/save/store/0');
@@ -69,6 +72,7 @@ public function testSaveActionChangeVisibility($attributes)
$session = $objectManager->get(\Magento\Backend\Model\Session::class);
$session->setProductIds([$product->getId()]);
$this->getRequest()->setParam('attributes', $attributes);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/catalog/product_action_attribute/save/store/0');
/** @var \Magento\Catalog\Model\Category $category */
@@ -89,6 +93,8 @@ public function testSaveActionChangeVisibility($attributes)
}
/**
+ * @param array $attributes Request parameter.
+ *
* @covers \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute\Validate::execute
*
* @dataProvider validateActionDataProvider
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php
index 4261873cc8e..98eb9d3ad4c 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/AttributeTest.php
@@ -6,10 +6,13 @@
namespace Magento\Catalog\Controller\Adminhtml\Product;
use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\App\Request\Http as HttpRequest;
/**
* @magentoAppArea adminhtml
* @magentoDbIsolation enabled
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class AttributeTest extends \Magento\TestFramework\TestCase\AbstractBackendController
{
@@ -25,6 +28,7 @@ public function testWrongFrontendInput()
'frontend_input' => 'some_input',
]
);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
$this->dispatch('backend/catalog/product_attribute/save');
$this->assertEquals(302, $this->getResponse()->getHttpResponseCode());
@@ -50,6 +54,7 @@ public function testWithPopup()
'popup' => 'true',
'new_attribute_set_name' => 'new_attribute_set',
];
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
$this->dispatch('backend/catalog/product_attribute/save');
$this->assertEquals(302, $this->getResponse()->getHttpResponseCode());
@@ -71,6 +76,7 @@ public function testWithExceptionWhenSaveAttribute()
{
$postData = $this->_getAttributeData() + ['attribute_id' => 0, 'frontend_input' => 'boolean'];
$this->getRequest()->setPostValue($postData);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/catalog/product_attribute/save');
$this->assertEquals(302, $this->getResponse()->getHttpResponseCode());
$this->assertContains(
@@ -89,6 +95,7 @@ public function testWrongAttributeId()
{
$postData = $this->_getAttributeData() + ['attribute_id' => 100500];
$this->getRequest()->setPostValue($postData);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/catalog/product_attribute/save');
$this->assertEquals(302, $this->getResponse()->getHttpResponseCode());
$this->assertContains(
@@ -113,6 +120,7 @@ public function testAttributeWithoutId()
'set' => 4,
'frontend_input' => 'boolean',
];
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
$this->dispatch('backend/catalog/product_attribute/save');
$this->assertEquals(302, $this->getResponse()->getHttpResponseCode());
@@ -135,6 +143,7 @@ public function testWrongAttributeCode()
{
$postData = $this->_getAttributeData() + ['attribute_code' => '_()&&&?'];
$this->getRequest()->setPostValue($postData);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/catalog/product_attribute/save');
$this->assertEquals(302, $this->getResponse()->getHttpResponseCode());
$this->assertContains(
@@ -159,6 +168,7 @@ public function testWrongAttributeCode()
public function testAttributeWithoutEntityTypeId()
{
$postData = $this->_getAttributeData() + ['attribute_id' => '2', 'new_attribute_set_name' => ' '];
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
$this->dispatch('backend/catalog/product_attribute/save');
$this->assertEquals(302, $this->getResponse()->getHttpResponseCode());
@@ -174,6 +184,7 @@ public function testAttributeWithoutEntityTypeId()
public function testSaveActionApplyToDataSystemAttribute()
{
$postData = $this->_getAttributeData() + ['attribute_id' => '2'];
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
$this->dispatch('backend/catalog/product_attribute/save');
$model = $this->_objectManager->create(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class);
@@ -187,6 +198,7 @@ public function testSaveActionApplyToDataSystemAttribute()
public function testSaveActionApplyToDataUserDefinedAttribute()
{
$postData = $this->_getAttributeData() + ['attribute_id' => '1'];
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
$this->dispatch('backend/catalog/product_attribute/save');
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $model */
@@ -202,6 +214,7 @@ public function testSaveActionApplyToData()
{
$postData = $this->_getAttributeData() + ['attribute_id' => '3'];
unset($postData['apply_to']);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
$this->dispatch('backend/catalog/product_attribute/save');
$model = $this->_objectManager->create(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class);
@@ -221,6 +234,7 @@ public function testSaveActionCleanAttributeLabelCache()
$this->assertEquals('predefined string translation', $this->_translate('string to translate'));
$string->saveTranslate('string to translate', 'new string translation');
$postData = $this->_getAttributeData() + ['attribute_id' => 1];
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
$this->dispatch('backend/catalog/product_attribute/save');
$this->assertEquals('new string translation', $this->_translate('string to translate'));
@@ -293,6 +307,7 @@ public function testLargeOptionsDataSet()
$optionsData []= "option[delete][option_{$i}=";
}
$attributeData['serialized_options'] = json_encode($optionsData);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($attributeData);
$this->dispatch('backend/catalog/product_attribute/save');
$entityTypeId = $this->_objectManager->create(
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/DeleteTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/DeleteTest.php
index 7c5d4ea48a2..7e034b8b3cb 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/DeleteTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/DeleteTest.php
@@ -6,6 +6,7 @@
namespace Magento\Catalog\Controller\Adminhtml\Product\Set;
use Magento\Framework\Message\MessageInterface;
+use Magento\Framework\App\Request\Http as HttpRequest;
class DeleteTest extends \Magento\TestFramework\TestCase\AbstractBackendController
{
@@ -15,7 +16,7 @@ class DeleteTest extends \Magento\TestFramework\TestCase\AbstractBackendControll
public function testDeleteById()
{
$attributeSet = $this->getAttributeSetByName('empty_attribute_set');
- $this->getRequest()->setParam('id', $attributeSet->getId());
+ $this->getRequest()->setParam('id', $attributeSet->getId())->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/catalog/product_set/delete/');
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php
index 5b711b2ea74..8ccd426424a 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php
@@ -9,6 +9,7 @@
use Magento\Eav\Api\Data\AttributeSetInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Framework\App\Request\Http as HttpRequest;
class SaveTest extends \Magento\TestFramework\TestCase\AbstractBackendController
{
@@ -20,6 +21,7 @@ public function testAlreadyExistsExceptionProcessingWhenGroupCodeIsDuplicated()
$attributeSet = $this->getAttributeSetByName('attribute_set_test');
$this->assertNotEmpty($attributeSet, 'Attribute set with name "attribute_set_test" is missed');
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue('data', json_encode([
'attribute_set_name' => 'attribute_set_test',
'groups' => [
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php
index 2877ef4fb36..06bbc43e36e 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php
@@ -6,17 +6,20 @@
namespace Magento\Catalog\Controller\Adminhtml;
use Magento\Framework\App\Request\DataPersistorInterface;
-use Magento\Framework\Data\Form\FormKey;
use Magento\Framework\Message\Manager;
-use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Framework\App\Request\Http as HttpRequest;
/**
* @magentoAppArea adminhtml
*/
class ProductTest extends \Magento\TestFramework\TestCase\AbstractBackendController
{
+ /**
+ * Test calling save with invalid product's ID.
+ */
public function testSaveActionWithDangerRequest()
{
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue(['product' => ['entity_id' => 15]]);
$this->dispatch('backend/catalog/product/save');
$this->assertSessionMessages(
@@ -27,6 +30,8 @@ public function testSaveActionWithDangerRequest()
}
/**
+ * Test saving existing product and specifying that we want redirect to new product form.
+ *
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
*/
public function testSaveActionAndNew()
@@ -34,6 +39,7 @@ public function testSaveActionAndNew()
$this->getRequest()->setPostValue(['back' => 'new']);
$repository = $this->_objectManager->create(\Magento\Catalog\Model\ProductRepository::class);
$product = $repository->get('simple');
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/catalog/product/save/id/' . $product->getEntityId());
$this->assertRedirect($this->stringStartsWith('http://localhost/index.php/backend/catalog/product/new/'));
$this->assertSessionMessages(
@@ -43,6 +49,9 @@ public function testSaveActionAndNew()
}
/**
+ * Test saving existing product and specifying that
+ * we want redirect to new product form with saved product's data applied.
+ *
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
*/
public function testSaveActionAndDuplicate()
@@ -50,6 +59,7 @@ public function testSaveActionAndDuplicate()
$this->getRequest()->setPostValue(['back' => 'duplicate']);
$repository = $this->_objectManager->create(\Magento\Catalog\Model\ProductRepository::class);
$product = $repository->get('simple');
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/catalog/product/save/id/' . $product->getEntityId());
$this->assertRedirect($this->stringStartsWith('http://localhost/index.php/backend/catalog/product/edit/'));
$this->assertRedirect(
@@ -69,6 +79,9 @@ public function testSaveActionAndDuplicate()
);
}
+ /**
+ * Testing Add Product button showing.
+ */
public function testIndexAction()
{
$this->dispatch('backend/catalog/product');
@@ -109,6 +122,8 @@ public function testIndexAction()
}
/**
+ * Testing existing product edit page.
+ *
* @magentoDataFixture Magento/Catalog/_files/product_simple.php
*/
public function testEditAction()
@@ -159,11 +174,13 @@ public function testEditAction()
public function testSaveActionWithAlreadyExistingUrlKey(array $postData)
{
$this->getRequest()->setPostValue($postData);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/catalog/product/save');
/** @var Manager $messageManager */
$messageManager = $this->_objectManager->get(Manager::class);
$messages = $messageManager->getMessages();
$errors = $messages->getItemsByType('error');
+ $this->assertNotEmpty($errors);
$message = array_shift($errors);
$this->assertSame('URL key for specified store already exists.', $message->getText());
$this->assertRedirect($this->stringContains('/backend/catalog/product/new'));
@@ -231,7 +248,6 @@ public function saveActionWithAlreadyExistingUrlKeyDataProvider()
'thumbnail' => '/m/a//magento_image.jpg.tmp',
'swatch_image' => '/m/a//magento_image.jpg.tmp',
],
- 'form_key' => Bootstrap::getObjectManager()->get(FormKey::class)->getFormKey(),
]
]
];
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Product/CompareTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Product/CompareTest.php
index ec2e97f9424..1cb2caace4f 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Product/CompareTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Product/CompareTest.php
@@ -7,6 +7,7 @@
namespace Magento\Catalog\Controller\Product;
use Magento\Framework\Message\MessageInterface;
+use Magento\Framework\App\Request\Http as HttpRequest;
/**
* @magentoDataFixture Magento/Catalog/controllers/_files/products.php
@@ -23,7 +24,7 @@ class CompareTest extends \Magento\TestFramework\TestCase\AbstractController
protected $productRepository;
/**
- * Test setup
+ * @inheritDoc
*/
protected function setUp()
{
@@ -36,6 +37,8 @@ protected function setUp()
}
/**
+ * Test adding product to compare list.
+ *
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function testAddAction()
@@ -45,6 +48,7 @@ public function testAddAction()
/** @var \Magento\Framework\Data\Form\FormKey $formKey */
$formKey = $objectManager->get(\Magento\Framework\Data\Form\FormKey::class);
$product = $this->productRepository->get('simple_product_1');
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch(
sprintf(
'catalog/product_compare/add/product/%s/form_key/%s?nocookie=1',
@@ -69,6 +73,8 @@ public function testAddAction()
}
/**
+ * Test comparing a product.
+ *
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function testIndexActionAddProducts()
@@ -83,12 +89,15 @@ public function testIndexActionAddProducts()
}
/**
+ * Test removing a product from compare list.
+ *
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function testRemoveAction()
{
$this->_requireVisitorWithTwoProducts();
$product = $this->productRepository->get('simple_product_2');
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('catalog/product_compare/remove/product/' . $product->getEntityId());
$this->assertSessionMessages(
@@ -102,12 +111,15 @@ public function testRemoveAction()
}
/**
+ * Test removing a product from compare list of a registered customer.
+ *
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function testRemoveActionWithSession()
{
$this->_requireCustomerWithTwoProducts();
$product = $this->productRepository->get('simple_product_1');
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('catalog/product_compare/remove/product/' . $product->getEntityId());
$secondProduct = $this->productRepository->get('simple_product_2');
@@ -122,7 +134,7 @@ public function testRemoveActionWithSession()
}
/**
- * testIndexActionDisplay
+ * Test getting a list of compared product.
*/
public function testIndexActionDisplay()
{
@@ -151,12 +163,13 @@ public function testIndexActionDisplay()
}
/**
- * testClearAction
+ * Test clearing a list of compared products.
*/
public function testClearAction()
{
$this->_requireVisitorWithTwoProducts();
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('catalog/product_compare/clear');
$this->assertSessionMessages(
@@ -170,12 +183,15 @@ public function testClearAction()
}
/**
+ * Test escaping a session message.
+ *
* @magentoDataFixture Magento/Catalog/_files/product_simple_xss.php
*/
public function testRemoveActionProductNameXss()
{
$this->_prepareCompareListWithProductNameXss();
$product = $this->productRepository->get('product-with-xss');
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('catalog/product_compare/remove/product/' . $product->getEntityId() . '?nocookie=1');
$this->assertSessionMessages(
@@ -187,6 +203,9 @@ public function testRemoveActionProductNameXss()
}
/**
+ * Preparing compare list.
+ *
+ * @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
protected function _prepareCompareListWithProductNameXss()
@@ -212,7 +231,9 @@ protected function _prepareCompareListWithProductNameXss()
}
/**
- * _requireVisitorWithNoProducts
+ * Preparing compare list.
+ *
+ * @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _requireVisitorWithNoProducts()
{
@@ -234,6 +255,9 @@ protected function _requireVisitorWithNoProducts()
}
/**
+ * Preparing compare list.
+ *
+ * @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
protected function _requireVisitorWithTwoProducts()
@@ -269,6 +293,9 @@ protected function _requireVisitorWithTwoProducts()
}
/**
+ * Preparing a compare list.
+ *
+ * @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
protected function _requireCustomerWithTwoProducts()
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
index a1260c0a7b1..c34120404a9 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
@@ -585,7 +585,7 @@ public function testGetOptions()
continue;
}
foreach ($option->getValues() as $value) {
- $this->assertEquals($expectedValue[$value->getSku()], floatval($value->getPrice()));
+ $this->assertEquals($expectedValue[$value->getSku()], (float)$value->getPrice());
}
}
}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wrong_url_key.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wrong_url_key.php
new file mode 100644
index 00000000000..5012bc94721
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wrong_url_key.php
@@ -0,0 +1,38 @@
+create(\Magento\Catalog\Model\Product::class);
+$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
+ ->setAttributeSetId(4)
+ ->setWebsiteIds([1])
+ ->setName('Simple Product')
+ ->setSku('simple1')
+ ->setPrice(10)
+ ->setDescription('Description with html tag')
+ ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
+ ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
+ ->setCategoryIds([2])
+ ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1])
+ ->setUrlKey('cuvee-merlot-cabernet-igp-pays-d-oc-frankrijk')
+ ->save();
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class);
+$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
+ ->setAttributeSetId(4)
+ ->setWebsiteIds([1])
+ ->setName('Simple Product 2')
+ ->setSku('simple2')
+ ->setPrice(10)
+ ->setDescription('Description with html tag')
+ ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
+ ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
+ ->setCategoryIds([2])
+ ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1])
+ ->setUrlKey('normal-url')
+ ->save();
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wrong_url_key_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wrong_url_key_rollback.php
new file mode 100644
index 00000000000..778fa7b15df
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_wrong_url_key_rollback.php
@@ -0,0 +1,29 @@
+getInstance()->reinitialize();
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
+$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+ ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+try {
+ $product = $productRepository->get('simple1', false, null, true);
+ $productRepository->delete($product);
+ $product = $productRepository->get('simple2', false, null, true);
+ $productRepository->delete($product);
+} catch (NoSuchEntityException $e) {
+}
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
index c5e704c2434..237d7660da9 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
@@ -1566,6 +1566,46 @@ public function testExistingProductWithUrlKeys()
}
}
+ /**
+ * @magentoDataFixture Magento/Catalog/_files/product_simple_with_wrong_url_key.php
+ * @magentoDbIsolation disabled
+ * @magentoAppIsolation enabled
+ */
+ public function testAddUpdateProductWithInvalidUrlKeys() : void
+ {
+ $products = [
+ 'simple1' => 'cuvee-merlot-cabernet-igp-pays-d-oc-frankrijk',
+ 'simple2' => 'normal-url',
+ 'simple3' => 'some-wrong-url'
+ ];
+ $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+ ->create(\Magento\Framework\Filesystem::class);
+ $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
+ $source = $this->objectManager->create(
+ \Magento\ImportExport\Model\Import\Source\Csv::class,
+ [
+ 'file' => __DIR__ . '/_files/products_to_import_with_invalid_url_keys.csv',
+ 'directory' => $directory
+ ]
+ );
+
+ $errors = $this->_model->setParameters(
+ ['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_ADD_UPDATE, 'entity' => 'catalog_product']
+ )->setSource(
+ $source
+ )->validateData();
+
+ $this->assertTrue($errors->getErrorsCount() == 0);
+ $this->_model->importData();
+
+ $productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+ \Magento\Catalog\Api\ProductRepositoryInterface::class
+ );
+ foreach ($products as $productSku => $productUrlKey) {
+ $this->assertEquals($productUrlKey, $productRepository->get($productSku)->getUrlKey());
+ }
+ }
+
/**
* @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php
* @magentoDbIsolation disabled
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_invalid_url_keys.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_invalid_url_keys.csv
new file mode 100644
index 00000000000..25bb95ab9e0
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_invalid_url_keys.csv
@@ -0,0 +1,4 @@
+sku,product_type,store_view_code,name,price,attribute_set_code,url_key
+simple1,simple,,"simple 1",25,Default,cuvée merlot-cabernet igp pays d'oc frankrijk
+simple2,simple,,"simple 2",34,Default,normal-url
+simple3,simple,,"simple 3",58,Default,some!wrong'url
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php
index 0ac6eb3c040..6105aba9201 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Quote/Item/QuantityValidatorTest.php
@@ -170,7 +170,7 @@ private function setMockStockStateResultToQuoteItemOptions($quoteItem, $resultMo
* Tests quantity verifications for configurable product.
*
* @param int $quantity - quantity of configurable option.
- * @param string $errorMessage - expected error message.
+ * @param string $errorMessageRegexp - expected error message regexp.
* @return void
* @throws CouldNotSaveException
* @throws LocalizedException
@@ -179,7 +179,7 @@ private function setMockStockStateResultToQuoteItemOptions($quoteItem, $resultMo
* @magentoDbIsolation enabled
* @magentoAppIsolation enabled
*/
- public function testConfigurableWithOptions(int $quantity, string $errorMessage): void
+ public function testConfigurableWithOptions(int $quantity, string $errorMessageRegexp): void
{
/** @var ProductRepositoryInterface $productRepository */
$productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
@@ -217,17 +217,16 @@ public function testConfigurableWithOptions(int $quantity, string $errorMessage)
]
);
- if (!empty($errorMessage)) {
- $this->expectException(LocalizedException::class);
- $this->expectExceptionMessage($errorMessage);
- }
-
- /** @var Quote $cart */
- $cart = $this->objectManager->create(CartInterface::class);
- $result = $cart->addProduct($product, $request);
+ try {
+ /** @var Quote $cart */
+ $cart = $this->objectManager->create(CartInterface::class);
+ $result = $cart->addProduct($product, $request);
- if (empty($errorMessage)) {
- self::assertEquals('Configurable Product', $result->getName());
+ if (empty($errorMessageRegexp)) {
+ self::assertEquals('Configurable Product', $result->getName());
+ }
+ } catch (LocalizedException $e) {
+ self::assertEquals(1, preg_match($errorMessageRegexp, $e->getMessage()));
}
}
@@ -239,18 +238,20 @@ public function testConfigurableWithOptions(int $quantity, string $errorMessage)
*/
public function quantityDataProvider(): array
{
+ $qtyRegexp = '/You can buy (this product|Configurable OptionOption 1) only in quantities of 500 at a time/';
+
return [
[
'quantity' => 1,
- 'error' => 'The fewest you may purchase is 500.'
+ 'error_regexp' => '/The fewest you may purchase is 500/'
],
[
'quantity' => 501,
- 'error' => 'You can buy Configurable OptionOption 1 only in quantities of 500 at a time'
+ 'error_regexp' => $qtyRegexp
],
[
'quantity' => 1000,
- 'error' => ''
+ 'error_regexp' => ''
],
];
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Controller/Cart/Index/CouponPostTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Controller/Cart/Index/CouponPostTest.php
index 07141843793..3e99c5cad3c 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/Controller/Cart/Index/CouponPostTest.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/Controller/Cart/Index/CouponPostTest.php
@@ -6,6 +6,8 @@
namespace Magento\Checkout\Controller\Cart\Index;
+use Magento\Framework\App\Request\Http as HttpRequest;
+
/**
* @magentoDbIsolation enabled
*/
@@ -26,6 +28,7 @@ public function testExecute()
'remove' => 0,
'coupon_code' => 'test'
];
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($inputData);
$this->dispatch(
'checkout/cart/couponPost/'
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php
index 033ce6185da..fc85cc384a3 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/Controller/CartTest.php
@@ -22,6 +22,7 @@
use Magento\Customer\Model\Session as CustomerSession;
use Magento\Sales\Model\ResourceModel\Order\Collection as OrderCollection;
use Magento\Sales\Model\ResourceModel\Order\Item\Collection as OrderItemCollection;
+use Magento\Framework\App\Request\Http as HttpRequest;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -239,6 +240,7 @@ public function testUpdatePostAction()
'update_cart_action' => 'update_qty',
'form_key' => $formKey->getFormKey(),
];
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
/** @var $customerSession \Magento\Customer\Model\Session */
$customerSession = $this->_objectManager->create(\Magento\Customer\Model\Session::class);
@@ -286,7 +288,8 @@ private function getQuote($reservedOrderId)
* Gets \Magento\Quote\Model\Quote\Item from \Magento\Quote\Model\Quote by product id
*
* @param \Magento\Quote\Model\Quote $quote
- * @param int $productId
+ * @param string|int $productId
+ *
* @return \Magento\Quote\Model\Quote\Item|null
*/
private function _getQuoteItemIdByProductId($quote, $productId)
@@ -321,6 +324,7 @@ public function testAddToCartSimpleProduct($area, $expectedPrice)
'isAjax' => 1
];
\Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea($area);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($postData);
$quote = $this->_objectManager->create(\Magento\Checkout\Model\Cart::class);
@@ -367,6 +371,7 @@ public function testMessageAtAddToCartWithRedirect()
];
\Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea('frontend');
$this->getRequest()->setPostValue($postData);
+ $this->getRequest()->setMethod('POST');
$this->dispatch('checkout/cart/add');
@@ -402,6 +407,7 @@ public function testMessageAtAddToCartWithoutRedirect()
];
\Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea('frontend');
$this->getRequest()->setPostValue($postData);
+ $this->getRequest()->setMethod('POST');
$this->dispatch('checkout/cart/add');
diff --git a/dev/tests/integration/testsuite/Magento/Cms/Block/Widget/BlockTest.php b/dev/tests/integration/testsuite/Magento/Cms/Block/Widget/BlockTest.php
index 7ee1f569180..266fd66bc3d 100644
--- a/dev/tests/integration/testsuite/Magento/Cms/Block/Widget/BlockTest.php
+++ b/dev/tests/integration/testsuite/Magento/Cms/Block/Widget/BlockTest.php
@@ -31,5 +31,6 @@ public function testToHtml()
$this->assertContains('', $result);
$this->assertContains('Custom variable: "HTML Value".
', $result);
+ $this->assertSame($cmsBlock->getIdentities(), $block->getIdentities());
}
}
diff --git a/dev/tests/integration/testsuite/Magento/Config/Controller/Adminhtml/System/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Config/Controller/Adminhtml/System/ConfigTest.php
index 2ad15fbea6c..24b68e804cd 100644
--- a/dev/tests/integration/testsuite/Magento/Config/Controller/Adminhtml/System/ConfigTest.php
+++ b/dev/tests/integration/testsuite/Magento/Config/Controller/Adminhtml/System/ConfigTest.php
@@ -7,12 +7,16 @@
namespace Magento\Config\Controller\Adminhtml\System;
use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Framework\App\Request\Http as HttpRequest;
/**
* @magentoAppArea adminhtml
*/
class ConfigTest extends \Magento\TestFramework\TestCase\AbstractBackendController
{
+ /**
+ * Test Configuration page existing.
+ */
public function testEditAction()
{
$this->dispatch('backend/admin/system_config/edit');
@@ -20,6 +24,8 @@ public function testEditAction()
}
/**
+ * Test redirect after changing base URL.
+ *
* @magentoAppIsolation enabled
* @magentoDbIsolation enabled
*/
@@ -43,6 +49,8 @@ public function testChangeBaseUrl()
)->setParam(
'section',
'web'
+ )->setMethod(
+ HttpRequest::METHOD_POST
);
$this->dispatch('backend/admin/system_config/save');
@@ -60,7 +68,9 @@ public function testChangeBaseUrl()
}
/**
- * Reset test framework default base url
+ * Reset test framework default base url.
+ *
+ * @param string $defaultHost
*/
protected function resetBaseUrl($defaultHost)
{
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php
index 4254a6ce9c7..b71507ae43f 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/ProductTest.php
@@ -9,6 +9,7 @@
use Magento\Framework\Registry;
use Magento\TestFramework\ObjectManager;
use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Framework\App\Request\Http as HttpRequest;
/**
* @magentoAppArea adminhtml
@@ -23,6 +24,7 @@ public function testSaveActionAssociatedProductIds()
{
$associatedProductIds = ['3', '14', '15', '92'];
$associatedProductIdsJSON = json_encode($associatedProductIds);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue(
[
'id' => 1,
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/CartTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/CartTest.php
index 4e0b74ba0f9..0d93d3ad4f4 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/CartTest.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Controller/CartTest.php
@@ -9,6 +9,8 @@
*/
namespace Magento\ConfigurableProduct\Controller;
+use Magento\Framework\App\Request\Http as HttpRequest;
+
class CartTest extends \Magento\TestFramework\TestCase\AbstractController
{
/**
@@ -85,6 +87,7 @@ public function testExecuteForConfigurableLastOption()
'remove' => 0,
'coupon_code' => 'test'
];
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()->setPostValue($inputData);
$this->dispatch(
'checkout/cart/couponPost/'
diff --git a/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php
index 2f89cb72b0c..c1255ae9b1a 100644
--- a/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Contact/Controller/IndexTest.php
@@ -6,7 +6,7 @@
namespace Magento\Contact\Controller;
-use Zend\Http\Request;
+use Magento\Framework\App\Request\Http as HttpRequest;
/**
* Contact index controller test
@@ -14,7 +14,7 @@
class IndexTest extends \Magento\TestFramework\TestCase\AbstractController
{
/**
- * testPostAction
+ * Test contacting.
*/
public function testPostAction()
{
@@ -24,8 +24,7 @@ public function testPostAction()
'email' => 'user@example.com',
'hideit' => '',
];
- $this->getRequest()->setPostValue($params);
- $this->getRequest()->setMethod(Request::METHOD_POST);
+ $this->getRequest()->setPostValue($params)->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('contact/index/post');
$this->assertRedirect($this->stringContains('contact/index'));
@@ -38,14 +37,16 @@ public function testPostAction()
}
/**
+ * Test validation.
+ *
+ * @param array $params For Request.
+ * @param string $expectedMessage Expected response.
+ *
* @dataProvider dataInvalidPostAction
- * @param array $params
- * @param string $expectedMessage
*/
public function testInvalidPostAction($params, $expectedMessage)
{
- $this->getRequest()->setPostValue($params);
- $this->getRequest()->setMethod(Request::METHOD_POST);
+ $this->getRequest()->setPostValue($params)->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('contact/index/post');
$this->assertRedirect($this->stringContains('contact/index'));
diff --git a/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRatesTest.php b/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRatesTest.php
index c9f2ffad676..fefd1a7b250 100644
--- a/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRatesTest.php
+++ b/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRatesTest.php
@@ -5,6 +5,8 @@
*/
namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currency;
+use Magento\Framework\App\Request\Http as HttpRequest;
+
class SaveRatesTest extends \Magento\TestFramework\TestCase\AbstractBackendController
{
@@ -43,6 +45,7 @@ public function testSaveAction()
$rate = 1.0000;
$request = $this->getRequest();
+ $request->setMethod(HttpRequest::METHOD_POST);
$request->setPostValue(
'rate',
[
@@ -75,6 +78,7 @@ public function testSaveWithWarningAction()
$rate = '0';
$request = $this->getRequest();
+ $request->setMethod(HttpRequest::METHOD_POST);
$request->setPostValue(
'rate',
[
diff --git a/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/SaveTest.php b/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/SaveTest.php
index 5217c3576a5..2929f137be8 100644
--- a/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/SaveTest.php
+++ b/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/SaveTest.php
@@ -5,10 +5,16 @@
*/
namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currencysymbol;
+use Magento\Framework\App\Request\Http as HttpRequest;
+
class SaveTest extends \Magento\TestFramework\TestCase\AbstractBackendController
{
/**
- * Test save action
+ * Test save action.
+ *
+ * @param string $currencyCode
+ * @param string $inputCurrencySymbol
+ * @param string $outputCurrencySymbol
*
* @magentoConfigFixture currency/options/allow USD
* @magentoDbIsolation enabled
@@ -31,6 +37,7 @@ public function testSaveAction($currencyCode, $inputCurrencySymbol, $outputCurre
$currencyCode => $inputCurrencySymbol,
]
);
+ $request->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/admin/system_currencysymbol/save');
$this->assertRedirect();
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php
index 186d9c8f87d..921fa81fa6f 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php
@@ -22,6 +22,7 @@
use Magento\TestFramework\Request;
use Magento\TestFramework\Response;
use Zend\Stdlib\Parameters;
+use Magento\Framework\App\Request\Http as HttpRequest;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -56,7 +57,7 @@ public function testIndexAction()
}
/**
- * @return void
+ * Test sign up form displaying.
*/
public function testCreateAction()
{
@@ -97,10 +98,8 @@ public function testForgotPasswordEmailMessageWithSpecialCharacters()
{
$email = 'customer@example.com';
- $this->getRequest()
- ->setPostValue([
- 'email' => $email,
- ]);
+ $this->getRequest()->setPostValue(['email' => $email]);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('customer/account/forgotPasswordPost');
$this->assertRedirect($this->stringContains('customer/account/'));
@@ -377,10 +376,8 @@ public function testForgotPasswordPostAction()
{
$email = 'customer@example.com';
- $this->getRequest()
- ->setPostValue([
- 'email' => $email,
- ]);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
+ $this->getRequest()->setPostValue(['email' => $email]);
$this->dispatch('customer/account/forgotPasswordPost');
$this->assertRedirect($this->stringContains('customer/account/'));
@@ -400,6 +397,7 @@ public function testForgotPasswordPostAction()
*/
public function testForgotPasswordPostWithBadEmailAction()
{
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->getRequest()
->setPostValue([
'email' => 'bad@email',
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php
index 32a622d4aa6..92e104496fe 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php
@@ -9,6 +9,7 @@
use Magento\Customer\Model\CustomerRegistry;
use Magento\Framework\Data\Form\FormKey;
use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Framework\App\Request\Http as HttpRequest;
class AddressTest extends \Magento\TestFramework\TestCase\AbstractController
{
@@ -19,7 +20,7 @@ class AddressTest extends \Magento\TestFramework\TestCase\AbstractController
private $formKey;
/**
- * {@inheritDoc}
+ * @inheritDoc
*/
protected function setUp()
{
@@ -168,7 +169,7 @@ public function testFailedFormPostAction()
public function testDeleteAction()
{
$this->getRequest()->setParam('id', 1);
- $this->getRequest()->setParam('form_key', $this->formKey->getFormKey());
+ $this->getRequest()->setParam('form_key', $this->formKey->getFormKey())->setMethod(HttpRequest::METHOD_POST);
// we are overwriting the address coming from the fixture
$this->dispatch('customer/address/delete');
@@ -186,7 +187,7 @@ public function testDeleteAction()
public function testWrongAddressDeleteAction()
{
$this->getRequest()->setParam('id', 555);
- $this->getRequest()->setParam('form_key', $this->formKey->getFormKey());
+ $this->getRequest()->setParam('form_key', $this->formKey->getFormKey())->setMethod(HttpRequest::METHOD_POST);
// we are overwriting the address coming from the fixture
$this->dispatch('customer/address/delete');
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/GroupTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/GroupTest.php
index 80b11a920e3..db1cc4995e6 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/GroupTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/GroupTest.php
@@ -7,6 +7,7 @@
use Magento\Framework\Message\MessageInterface;
use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Framework\App\Request\Http as HttpRequest;
/**
* @magentoAppArea adminhtml
@@ -25,6 +26,11 @@ class GroupTest extends \Magento\TestFramework\TestCase\AbstractBackendControlle
/** @var \Magento\Customer\Api\GroupRepositoryInterface */
private $groupRepository;
+ /**
+ * @inheritDoc
+ *
+ * @throws \Magento\Framework\Exception\AuthenticationException
+ */
public function setUp()
{
parent::setUp();
@@ -33,12 +39,18 @@ public function setUp()
$this->groupRepository = $objectManager->get(\Magento\Customer\Api\GroupRepositoryInterface::class);
}
+ /**
+ * @inheritDoc
+ */
public function tearDown()
{
parent::tearDown();
//$this->session->unsCustomerGroupData();
}
+ /**
+ * Test new group form.
+ */
public function testNewActionNoCustomerGroupDataInSession()
{
$this->dispatch('backend/customer/group/new');
@@ -49,6 +61,9 @@ public function testNewActionNoCustomerGroupDataInSession()
$this->assertContains($expected, $responseBody);
}
+ /**
+ * Test form filling with data in session.
+ */
public function testNewActionWithCustomerGroupDataInSession()
{
/** @var \Magento\Customer\Api\Data\GroupInterfaceFactory $customerGroupFactory */
@@ -76,21 +91,27 @@ public function testNewActionWithCustomerGroupDataInSession()
}
/**
+ * Test calling delete without an ID.
+ *
* @magentoDataFixture Magento/Customer/_files/customer_group.php
*/
public function testDeleteActionNoGroupId()
{
+ $this->getRequest()->setMethod(\Magento\Framework\App\Request\Http::METHOD_POST);
$this->dispatch('backend/customer/group/delete');
$this->assertRedirect($this->stringStartsWith(self::BASE_CONTROLLER_URL));
}
/**
+ * Test deleting a group.
+ *
* @magentoDataFixture Magento/Customer/_files/customer_group.php
*/
public function testDeleteActionExistingGroup()
{
$groupId = $this->findGroupIdWithCode(self::CUSTOMER_GROUP_CODE);
$this->getRequest()->setParam('id', $groupId);
+ $this->getRequest()->setMethod(\Magento\Framework\App\Request\Http::METHOD_POST);
$this->dispatch('backend/customer/group/delete');
/**
@@ -104,11 +125,14 @@ public function testDeleteActionExistingGroup()
}
/**
+ * Tet deleting with wrong ID.
+ *
* @magentoDataFixture Magento/Customer/_files/customer_group.php
*/
public function testDeleteActionNonExistingGroupId()
{
$this->getRequest()->setParam('id', 10000);
+ $this->getRequest()->setMethod(\Magento\Framework\App\Request\Http::METHOD_POST);
$this->dispatch('backend/customer/group/delete');
/**
@@ -122,6 +146,8 @@ public function testDeleteActionNonExistingGroupId()
}
/**
+ * Test saving a valid group.
+ *
* @magentoDataFixture Magento/Customer/_files/customer_group.php
*/
public function testSaveActionExistingGroup()
@@ -130,6 +156,7 @@ public function testSaveActionExistingGroup()
$this->getRequest()->setParam('tax_class', self::TAX_CLASS_ID);
$this->getRequest()->setParam('id', $groupId);
$this->getRequest()->setParam('code', self::CUSTOMER_GROUP_CODE);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/customer/group/save');
@@ -161,9 +188,13 @@ public function testSaveActionExistingGroup()
);
}
+ /**
+ * Test saving an invalid group.
+ */
public function testSaveActionCreateNewGroupWithoutCode()
{
$this->getRequest()->setParam('tax_class', self::TAX_CLASS_ID);
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/customer/group/save');
@@ -173,19 +204,26 @@ public function testSaveActionCreateNewGroupWithoutCode()
);
}
+ /**
+ * Test saving an empty group.
+ */
public function testSaveActionForwardNewCreateNewGroup()
{
+ $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
$this->dispatch('backend/customer/group/save');
$responseBody = $this->getResponse()->getBody();
$this->assertRegExp('/