mirror of
https://github.com/bdnugget/magento2.git
synced 2026-11-07 09:17:35 +00:00
Merge pull request #8703 from magento-l3/PR_10_JAN_2024
[Tier 4] Bug fix delivery
This commit is contained in:
commit
57a32313c4
17 files changed
+491
-99
No files matched your search
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2024 Adobe
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* NOTICE: All information contained herein is, and remains
|
||||
* the property of Adobe and its suppliers, if any. The intellectual
|
||||
* and technical concepts contained herein are proprietary to Adobe
|
||||
* and its suppliers and are protected by all applicable intellectual
|
||||
* property laws, including trade secret and copyright laws.
|
||||
* Dissemination of this information or reproduction of this material
|
||||
* is strictly forbidden unless prior written permission is obtained
|
||||
* from Adobe.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\Catalog\Model\Category\Attribute\Backend;
|
||||
|
||||
class DefaultSortby extends Sortby
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2024 Adobe
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* NOTICE: All information contained herein is, and remains
|
||||
* the property of Adobe and its suppliers, if any. The intellectual
|
||||
* and technical concepts contained herein are proprietary to Adobe
|
||||
* and its suppliers and are protected by all applicable intellectual
|
||||
* property laws, including trade secret and copyright laws.
|
||||
* Dissemination of this information or reproduction of this material
|
||||
* is strictly forbidden unless prior written permission is obtained
|
||||
* from Adobe.
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Magento\Catalog\Setup\Patch\Data;
|
||||
|
||||
use Magento\Catalog\Setup\CategorySetup;
|
||||
use Magento\Catalog\Setup\CategorySetupFactory;
|
||||
use Magento\Framework\Setup\ModuleDataSetupInterface;
|
||||
use Magento\Framework\Setup\Patch\DataPatchInterface;
|
||||
use Magento\Framework\Setup\Patch\PatchInterface;
|
||||
|
||||
class UpdateDefaultSortyByBackendType implements DataPatchInterface
|
||||
{
|
||||
/**
|
||||
* @var ModuleDataSetupInterface
|
||||
*/
|
||||
private $moduleDataSetup;
|
||||
|
||||
/**
|
||||
* @var CategorySetupFactory
|
||||
*/
|
||||
private $categorySetupFactory;
|
||||
|
||||
/**
|
||||
* PatchInitial constructor.
|
||||
* @param ModuleDataSetupInterface $moduleDataSetup
|
||||
* @param CategorySetupFactory $categorySetupFactory
|
||||
*/
|
||||
public function __construct(
|
||||
ModuleDataSetupInterface $moduleDataSetup,
|
||||
CategorySetupFactory $categorySetupFactory
|
||||
) {
|
||||
$this->moduleDataSetup = $moduleDataSetup;
|
||||
$this->categorySetupFactory = $categorySetupFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function apply(): UpdateDefaultSortyByBackendType
|
||||
{
|
||||
$mediaBackendModel = \Magento\Catalog\Model\Category\Attribute\Backend\DefaultSortby::class;
|
||||
/** @var CategorySetup $categorySetup */
|
||||
$categorySetup = $this->categorySetupFactory->create(['setup' => $this->moduleDataSetup]);
|
||||
$categorySetup->updateAttribute(
|
||||
'catalog_category',
|
||||
'default_sort_by',
|
||||
'backend_model',
|
||||
$mediaBackendModel
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function getDependencies()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAliases()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ class Category implements RevertibleDataFixtureInterface
|
||||
'include_in_menu' => true,
|
||||
'available_sort_by' => [],
|
||||
'custom_attributes' => [
|
||||
'default_sort_by' => ['name']
|
||||
'default_sort_by' => 'position'
|
||||
],
|
||||
'extension_attributes' => [],
|
||||
'created_at' => null,
|
||||
|
||||
@@ -740,6 +740,7 @@
|
||||
<item name="Magento\Catalog\Model\Product\Attribute\Backend\Category" xsi:type="string">int[]</item>
|
||||
<item name="Magento\Catalog\Model\Product\Attribute\Backend\Stock" xsi:type="string">Magento\CatalogInventory\Api\Data\StockItemInterface[]</item>
|
||||
<item name="Magento\Catalog\Model\Category\Attribute\Backend\Sortby" xsi:type="string">string[]</item>
|
||||
<item name="Magento\Catalog\Model\Category\Attribute\Backend\DefaultSortby" xsi:type="string">string</item>
|
||||
</argument>
|
||||
</arguments>
|
||||
</type>
|
||||
|
||||
@@ -6,7 +6,17 @@
|
||||
|
||||
namespace Magento\CheckoutAgreements\Model\Checkout\Plugin;
|
||||
|
||||
use Magento\Checkout\Api\AgreementsValidatorInterface;
|
||||
use Magento\Checkout\Api\GuestPaymentInformationManagementInterface;
|
||||
use Magento\CheckoutAgreements\Api\CheckoutAgreementsListInterface;
|
||||
use Magento\CheckoutAgreements\Model\AgreementsProvider;
|
||||
use Magento\Framework\App\Config\ScopeConfigInterface;
|
||||
use Magento\Framework\Exception\CouldNotSaveException;
|
||||
use Magento\Framework\Exception\NoSuchEntityException;
|
||||
use Magento\Quote\Api\Data\AddressInterface;
|
||||
use Magento\Quote\Api\Data\PaymentInterface;
|
||||
use Magento\Quote\Api\GuestCartRepositoryInterface;
|
||||
use Magento\Store\Model\App\Emulation;
|
||||
use Magento\Store\Model\ScopeInterface;
|
||||
use Magento\CheckoutAgreements\Model\Api\SearchCriteria\ActiveStoreAgreementsFilter;
|
||||
|
||||
@@ -40,62 +50,85 @@ class GuestValidation
|
||||
private $activeStoreAgreementsFilter;
|
||||
|
||||
/**
|
||||
* @param \Magento\Checkout\Api\AgreementsValidatorInterface $agreementsValidator
|
||||
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfiguration
|
||||
* @param \Magento\CheckoutAgreements\Api\CheckoutAgreementsListInterface $checkoutAgreementsList
|
||||
* @var GuestCartRepositoryInterface
|
||||
*/
|
||||
private GuestCartRepositoryInterface $quoteRepository;
|
||||
|
||||
/**
|
||||
* @var Emulation
|
||||
*/
|
||||
private Emulation $storeEmulation;
|
||||
|
||||
/**
|
||||
* @param AgreementsValidatorInterface $agreementsValidator
|
||||
* @param ScopeConfigInterface $scopeConfiguration
|
||||
* @param CheckoutAgreementsListInterface $checkoutAgreementsList
|
||||
* @param ActiveStoreAgreementsFilter $activeStoreAgreementsFilter
|
||||
* @param GuestCartRepositoryInterface $quoteRepository
|
||||
* @param Emulation $storeEmulation
|
||||
*/
|
||||
public function __construct(
|
||||
\Magento\Checkout\Api\AgreementsValidatorInterface $agreementsValidator,
|
||||
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfiguration,
|
||||
\Magento\CheckoutAgreements\Api\CheckoutAgreementsListInterface $checkoutAgreementsList,
|
||||
\Magento\CheckoutAgreements\Model\Api\SearchCriteria\ActiveStoreAgreementsFilter $activeStoreAgreementsFilter
|
||||
\Magento\CheckoutAgreements\Model\Api\SearchCriteria\ActiveStoreAgreementsFilter $activeStoreAgreementsFilter,
|
||||
GuestCartRepositoryInterface $quoteRepository,
|
||||
Emulation $storeEmulation
|
||||
) {
|
||||
$this->agreementsValidator = $agreementsValidator;
|
||||
$this->scopeConfiguration = $scopeConfiguration;
|
||||
$this->checkoutAgreementsList = $checkoutAgreementsList;
|
||||
$this->activeStoreAgreementsFilter = $activeStoreAgreementsFilter;
|
||||
$this->quoteRepository = $quoteRepository;
|
||||
$this->storeEmulation = $storeEmulation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates agreements before save payment information and order placing.
|
||||
*
|
||||
* @param \Magento\Checkout\Api\GuestPaymentInformationManagementInterface $subject
|
||||
* @param GuestPaymentInformationManagementInterface $subject
|
||||
* @param string $cartId
|
||||
* @param string $email
|
||||
* @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
|
||||
* @param \Magento\Quote\Api\Data\AddressInterface|null $billingAddress
|
||||
* @throws \Magento\Framework\Exception\CouldNotSaveException
|
||||
* @param PaymentInterface $paymentMethod
|
||||
* @param AddressInterface|null $billingAddress
|
||||
* @return void
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
* @throws CouldNotSaveException|NoSuchEntityException
|
||||
*/
|
||||
public function beforeSavePaymentInformationAndPlaceOrder(
|
||||
\Magento\Checkout\Api\GuestPaymentInformationManagementInterface $subject,
|
||||
GuestPaymentInformationManagementInterface $subject,
|
||||
$cartId,
|
||||
$email,
|
||||
\Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
|
||||
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
|
||||
PaymentInterface $paymentMethod,
|
||||
AddressInterface $billingAddress = null
|
||||
) {
|
||||
if ($this->isAgreementEnabled()) {
|
||||
$this->validateAgreements($paymentMethod);
|
||||
$quote = $this->quoteRepository->get($cartId);
|
||||
$storeId = $quote->getStoreId();
|
||||
$this->validateAgreements($paymentMethod, $storeId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates agreements.
|
||||
*
|
||||
* @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
|
||||
* @throws \Magento\Framework\Exception\CouldNotSaveException
|
||||
* @param PaymentInterface $paymentMethod
|
||||
* @param int $storeId
|
||||
* @return void
|
||||
* @throws CouldNotSaveException
|
||||
*/
|
||||
private function validateAgreements(\Magento\Quote\Api\Data\PaymentInterface $paymentMethod)
|
||||
private function validateAgreements(PaymentInterface $paymentMethod, int $storeId)
|
||||
{
|
||||
$agreements = $paymentMethod->getExtensionAttributes() === null
|
||||
? []
|
||||
: $paymentMethod->getExtensionAttributes()->getAgreementIds();
|
||||
|
||||
if (!$this->agreementsValidator->isValid($agreements)) {
|
||||
throw new \Magento\Framework\Exception\CouldNotSaveException(
|
||||
$this->storeEmulation->startEnvironmentEmulation($storeId);
|
||||
$isValid = $this->agreementsValidator->isValid($agreements);
|
||||
$this->storeEmulation->stopEnvironmentEmulation();
|
||||
|
||||
if (!$isValid) {
|
||||
throw new CouldNotSaveException(
|
||||
__(
|
||||
"The order wasn't placed. "
|
||||
. "First, agree to the terms and conditions, then try placing your order again."
|
||||
|
||||
@@ -6,9 +6,16 @@
|
||||
|
||||
namespace Magento\CheckoutAgreements\Model\Checkout\Plugin;
|
||||
|
||||
use Magento\Checkout\Api\AgreementsValidatorInterface;
|
||||
use Magento\CheckoutAgreements\Api\CheckoutAgreementsListInterface;
|
||||
use Magento\CheckoutAgreements\Model\AgreementsProvider;
|
||||
use Magento\CheckoutAgreements\Model\Api\SearchCriteria\ActiveStoreAgreementsFilter;
|
||||
use Magento\CheckoutAgreements\Model\EmulateStore;
|
||||
use Magento\Framework\App\Config\ScopeConfigInterface;
|
||||
use Magento\Framework\Exception\CouldNotSaveException;
|
||||
use Magento\Quote\Api\CartRepositoryInterface;
|
||||
use Magento\Quote\Api\Data\PaymentInterface;
|
||||
use Magento\Store\Model\App\Emulation;
|
||||
use Magento\Store\Model\ScopeInterface;
|
||||
|
||||
/**
|
||||
@@ -37,31 +44,37 @@ class Validation
|
||||
private $activeStoreAgreementsFilter;
|
||||
|
||||
/**
|
||||
* Quote repository.
|
||||
*
|
||||
* @var \Magento\Quote\Api\CartRepositoryInterface
|
||||
*/
|
||||
private $quoteRepository;
|
||||
|
||||
/**
|
||||
* @param \Magento\Checkout\Api\AgreementsValidatorInterface $agreementsValidator
|
||||
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfiguration
|
||||
* @param \Magento\CheckoutAgreements\Api\CheckoutAgreementsListInterface $checkoutAgreementsList
|
||||
* @var Emulation
|
||||
*/
|
||||
private Emulation $storeEmulation;
|
||||
|
||||
/**
|
||||
* @param AgreementsValidatorInterface $agreementsValidator
|
||||
* @param ScopeConfigInterface $scopeConfiguration
|
||||
* @param CheckoutAgreementsListInterface $checkoutAgreementsList
|
||||
* @param ActiveStoreAgreementsFilter $activeStoreAgreementsFilter
|
||||
* @param CartRepositoryInterface $quoteRepository
|
||||
* @param Emulation $storeEmulation
|
||||
*/
|
||||
public function __construct(
|
||||
\Magento\Checkout\Api\AgreementsValidatorInterface $agreementsValidator,
|
||||
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfiguration,
|
||||
\Magento\CheckoutAgreements\Api\CheckoutAgreementsListInterface $checkoutAgreementsList,
|
||||
\Magento\CheckoutAgreements\Model\Api\SearchCriteria\ActiveStoreAgreementsFilter $activeStoreAgreementsFilter,
|
||||
CartRepositoryInterface $quoteRepository
|
||||
CartRepositoryInterface $quoteRepository,
|
||||
Emulation $storeEmulation
|
||||
) {
|
||||
$this->agreementsValidator = $agreementsValidator;
|
||||
$this->scopeConfiguration = $scopeConfiguration;
|
||||
$this->checkoutAgreementsList = $checkoutAgreementsList;
|
||||
$this->activeStoreAgreementsFilter = $activeStoreAgreementsFilter;
|
||||
$this->quoteRepository = $quoteRepository;
|
||||
$this->storeEmulation = $storeEmulation;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,24 +95,31 @@ class Validation
|
||||
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
|
||||
) {
|
||||
if ($this->isAgreementEnabled()) {
|
||||
$this->validateAgreements($paymentMethod);
|
||||
$quote = $this->quoteRepository->get($cartId);
|
||||
$storeId = $quote->getStoreId();
|
||||
$this->validateAgreements($paymentMethod, $storeId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate agreements base on the payment method
|
||||
*
|
||||
* @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
|
||||
* @throws \Magento\Framework\Exception\CouldNotSaveException
|
||||
* @param PaymentInterface $paymentMethod
|
||||
* @param int $storeId
|
||||
* @return void
|
||||
* @throws CouldNotSaveException
|
||||
*/
|
||||
protected function validateAgreements(\Magento\Quote\Api\Data\PaymentInterface $paymentMethod)
|
||||
private function validateAgreements(\Magento\Quote\Api\Data\PaymentInterface $paymentMethod, int $storeId)
|
||||
{
|
||||
$agreements = $paymentMethod->getExtensionAttributes() === null
|
||||
? []
|
||||
: $paymentMethod->getExtensionAttributes()->getAgreementIds();
|
||||
|
||||
if (!$this->agreementsValidator->isValid($agreements)) {
|
||||
$this->storeEmulation->startEnvironmentEmulation($storeId);
|
||||
$isValid = $this->agreementsValidator->isValid($agreements);
|
||||
$this->storeEmulation->stopEnvironmentEmulation();
|
||||
|
||||
if (!$isValid) {
|
||||
throw new \Magento\Framework\Exception\CouldNotSaveException(
|
||||
__(
|
||||
"The order wasn't placed. "
|
||||
|
||||
+59
-6
@@ -15,9 +15,14 @@ use Magento\CheckoutAgreements\Model\Api\SearchCriteria\ActiveStoreAgreementsFil
|
||||
use Magento\CheckoutAgreements\Model\Checkout\Plugin\GuestValidation;
|
||||
use Magento\Framework\Api\SearchCriteria;
|
||||
use Magento\Framework\App\Config\ScopeConfigInterface;
|
||||
use Magento\Quote\Api\CartRepositoryInterface;
|
||||
use Magento\Quote\Api\Data\AddressInterface;
|
||||
use Magento\Quote\Api\Data\PaymentExtension;
|
||||
use Magento\Quote\Api\Data\PaymentExtensionInterface;
|
||||
use Magento\Quote\Api\Data\PaymentInterface;
|
||||
use Magento\Quote\Api\GuestCartRepositoryInterface;
|
||||
use Magento\Quote\Model\MaskedQuoteIdToQuoteId;
|
||||
use Magento\Quote\Model\Quote;
|
||||
use Magento\Store\Model\App\Emulation;
|
||||
use Magento\Store\Model\ScopeInterface;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\MockObject\RuntimeException;
|
||||
@@ -73,6 +78,26 @@ class GuestValidationTest extends TestCase
|
||||
*/
|
||||
private $agreementsFilterMock;
|
||||
|
||||
/**
|
||||
* @var Quote|MockObject
|
||||
*/
|
||||
private Quote|MockObject $quoteMock;
|
||||
|
||||
/**
|
||||
* @var MaskedQuoteIdToQuoteId|MockObject
|
||||
*/
|
||||
private MaskedQuoteIdToQuoteId|MockObject $maskedQuoteIdToQuoteIdMock;
|
||||
|
||||
/**
|
||||
* @var CartRepositoryInterface|MockObject
|
||||
*/
|
||||
private CartRepositoryInterface|MockObject $cartRepositoryMock;
|
||||
|
||||
/**
|
||||
* @var Emulation|MockObject
|
||||
*/
|
||||
private Emulation|MockObject $storeEmulationMock;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->agreementsValidatorMock = $this->getMockForAbstractClass(AgreementsValidatorInterface::class);
|
||||
@@ -87,18 +112,34 @@ class GuestValidationTest extends TestCase
|
||||
$this->agreementsFilterMock = $this->createMock(
|
||||
ActiveStoreAgreementsFilter::class
|
||||
);
|
||||
$this->quoteMock = $this->createMock(Quote::class);
|
||||
$this->maskedQuoteIdToQuoteIdMock = $this->createMock(MaskedQuoteIdToQuoteId::class);
|
||||
$this->cartRepositoryMock = $this->createMock(GuestCartRepositoryInterface::class);
|
||||
$this->storeEmulationMock = $this->createMock(Emulation::class);
|
||||
|
||||
$storeId = 1;
|
||||
$this->quoteMock->expects($this->once())
|
||||
->method('getStoreId')
|
||||
->willReturn($storeId);
|
||||
$this->cartRepositoryMock->expects($this->once())
|
||||
->method('get')
|
||||
->with('0CQwCntNHR4yN9P5PUAzbxatvDvBXOce')
|
||||
->willReturn($this->quoteMock);
|
||||
|
||||
$this->model = new GuestValidation(
|
||||
$this->agreementsValidatorMock,
|
||||
$this->scopeConfigMock,
|
||||
$this->checkoutAgreementsListMock,
|
||||
$this->agreementsFilterMock
|
||||
$this->agreementsFilterMock,
|
||||
$this->cartRepositoryMock,
|
||||
$this->storeEmulationMock
|
||||
);
|
||||
}
|
||||
|
||||
public function testBeforeSavePaymentInformationAndPlaceOrder()
|
||||
{
|
||||
$cartId = '100';
|
||||
$storeId = 1;
|
||||
$cartId = '0CQwCntNHR4yN9P5PUAzbxatvDvBXOce';
|
||||
$email = 'email@example.com';
|
||||
$agreements = [1, 2, 3];
|
||||
$this->scopeConfigMock
|
||||
@@ -119,6 +160,11 @@ class GuestValidationTest extends TestCase
|
||||
$this->paymentMock->expects(static::atLeastOnce())
|
||||
->method('getExtensionAttributes')
|
||||
->willReturn($this->extensionAttributesMock);
|
||||
$this->storeEmulationMock->expects($this->once())
|
||||
->method('startEnvironmentEmulation')
|
||||
->with($storeId);
|
||||
$this->storeEmulationMock->expects($this->once())
|
||||
->method('stopEnvironmentEmulation');
|
||||
$this->model->beforeSavePaymentInformationAndPlaceOrder(
|
||||
$this->subjectMock,
|
||||
$cartId,
|
||||
@@ -131,7 +177,8 @@ class GuestValidationTest extends TestCase
|
||||
public function testBeforeSavePaymentInformationAndPlaceOrderIfAgreementsNotValid()
|
||||
{
|
||||
$this->expectException('Magento\Framework\Exception\CouldNotSaveException');
|
||||
$cartId = 100;
|
||||
$storeId = 1;
|
||||
$cartId = '0CQwCntNHR4yN9P5PUAzbxatvDvBXOce';
|
||||
$email = 'email@example.com';
|
||||
$agreements = [1, 2, 3];
|
||||
$this->scopeConfigMock
|
||||
@@ -152,6 +199,11 @@ class GuestValidationTest extends TestCase
|
||||
$this->paymentMock->expects(static::atLeastOnce())
|
||||
->method('getExtensionAttributes')
|
||||
->willReturn($this->extensionAttributesMock);
|
||||
$this->storeEmulationMock->expects($this->once())
|
||||
->method('startEnvironmentEmulation')
|
||||
->with($storeId);
|
||||
$this->storeEmulationMock->expects($this->once())
|
||||
->method('stopEnvironmentEmulation');
|
||||
$this->model->beforeSavePaymentInformationAndPlaceOrder(
|
||||
$this->subjectMock,
|
||||
$cartId,
|
||||
@@ -172,9 +224,10 @@ class GuestValidationTest extends TestCase
|
||||
*/
|
||||
private function getPaymentExtension(): MockObject
|
||||
{
|
||||
$mockBuilder = $this->getMockBuilder(PaymentExtension::class);
|
||||
$mockBuilder = $this->getMockBuilder(PaymentExtensionInterface::class)
|
||||
->disableOriginalConstructor();
|
||||
try {
|
||||
$mockBuilder->addMethods(['getAgreementIds']);
|
||||
$mockBuilder->addMethods(['getAgreementIds', 'setAgreementIds']);
|
||||
} catch (RuntimeException $e) {
|
||||
// Payment extension already generated.
|
||||
}
|
||||
|
||||
+35
-5
@@ -13,13 +13,15 @@ use Magento\CheckoutAgreements\Api\CheckoutAgreementsListInterface;
|
||||
use Magento\CheckoutAgreements\Model\AgreementsProvider;
|
||||
use Magento\CheckoutAgreements\Model\Api\SearchCriteria\ActiveStoreAgreementsFilter;
|
||||
use Magento\CheckoutAgreements\Model\Checkout\Plugin\Validation;
|
||||
use Magento\CheckoutAgreements\Model\EmulateStore;
|
||||
use Magento\Framework\Api\SearchCriteria;
|
||||
use Magento\Framework\App\Config\ScopeConfigInterface;
|
||||
use Magento\Quote\Api\CartRepositoryInterface;
|
||||
use Magento\Quote\Api\Data\AddressInterface;
|
||||
use Magento\Quote\Api\Data\PaymentExtension;
|
||||
use Magento\Quote\Api\Data\PaymentExtensionInterface;
|
||||
use Magento\Quote\Api\Data\PaymentInterface;
|
||||
use Magento\Quote\Model\Quote;
|
||||
use Magento\Store\Model\App\Emulation;
|
||||
use Magento\Store\Model\ScopeInterface;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\MockObject\RuntimeException;
|
||||
@@ -86,6 +88,11 @@ class ValidationTest extends TestCase
|
||||
*/
|
||||
private $quoteRepositoryMock;
|
||||
|
||||
/**
|
||||
* @var Emulation|MockObject
|
||||
*/
|
||||
private Emulation|MockObject $storeEmulationMock;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->agreementsValidatorMock = $this->getMockForAbstractClass(AgreementsValidatorInterface::class);
|
||||
@@ -94,6 +101,7 @@ class ValidationTest extends TestCase
|
||||
$this->addressMock = $this->getMockForAbstractClass(AddressInterface::class);
|
||||
$this->quoteMock = $this->getMockBuilder(Quote::class)
|
||||
->addMethods(['getIsMultiShipping'])
|
||||
->onlyMethods(['getStoreId'])
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->quoteRepositoryMock = $this->getMockForAbstractClass(CartRepositoryInterface::class);
|
||||
@@ -105,18 +113,29 @@ class ValidationTest extends TestCase
|
||||
$this->agreementsFilterMock = $this->createMock(
|
||||
ActiveStoreAgreementsFilter::class
|
||||
);
|
||||
$this->storeEmulationMock = $this->createMock(Emulation::class);
|
||||
|
||||
$storeId = 1;
|
||||
$this->quoteMock->expects($this->once())
|
||||
->method('getStoreId')
|
||||
->willReturn($storeId);
|
||||
$this->quoteRepositoryMock->expects($this->once())
|
||||
->method('get')
|
||||
->willReturn($this->quoteMock);
|
||||
|
||||
$this->model = new Validation(
|
||||
$this->agreementsValidatorMock,
|
||||
$this->scopeConfigMock,
|
||||
$this->checkoutAgreementsListMock,
|
||||
$this->agreementsFilterMock,
|
||||
$this->quoteRepositoryMock
|
||||
$this->quoteRepositoryMock,
|
||||
$this->storeEmulationMock
|
||||
);
|
||||
}
|
||||
|
||||
public function testBeforeSavePaymentInformationAndPlaceOrder()
|
||||
{
|
||||
$storeId = 1;
|
||||
$cartId = 100;
|
||||
$agreements = [1, 2, 3];
|
||||
$this->scopeConfigMock
|
||||
@@ -144,6 +163,11 @@ class ValidationTest extends TestCase
|
||||
$this->paymentMock->expects(static::atLeastOnce())
|
||||
->method('getExtensionAttributes')
|
||||
->willReturn($this->extensionAttributesMock);
|
||||
$this->storeEmulationMock->expects($this->once())
|
||||
->method('startEnvironmentEmulation')
|
||||
->with($storeId);
|
||||
$this->storeEmulationMock->expects($this->once())
|
||||
->method('stopEnvironmentEmulation');
|
||||
$this->model->beforeSavePaymentInformationAndPlaceOrder(
|
||||
$this->subjectMock,
|
||||
$cartId,
|
||||
@@ -155,6 +179,7 @@ class ValidationTest extends TestCase
|
||||
public function testBeforeSavePaymentInformationAndPlaceOrderIfAgreementsNotValid()
|
||||
{
|
||||
$this->expectException('Magento\Framework\Exception\CouldNotSaveException');
|
||||
$storeId = 1;
|
||||
$cartId = 100;
|
||||
$agreements = [1, 2, 3];
|
||||
$this->scopeConfigMock
|
||||
@@ -182,13 +207,17 @@ class ValidationTest extends TestCase
|
||||
$this->paymentMock->expects(static::atLeastOnce())
|
||||
->method('getExtensionAttributes')
|
||||
->willReturn($this->extensionAttributesMock);
|
||||
$this->storeEmulationMock->expects($this->once())
|
||||
->method('startEnvironmentEmulation')
|
||||
->with($storeId);
|
||||
$this->storeEmulationMock->expects($this->once())
|
||||
->method('stopEnvironmentEmulation');
|
||||
$this->model->beforeSavePaymentInformationAndPlaceOrder(
|
||||
$this->subjectMock,
|
||||
$cartId,
|
||||
$this->paymentMock,
|
||||
$this->addressMock
|
||||
);
|
||||
|
||||
$this->expectExceptionMessage(
|
||||
"The order wasn't placed. First, agree to the terms and conditions, then try placing your order again."
|
||||
);
|
||||
@@ -201,9 +230,10 @@ class ValidationTest extends TestCase
|
||||
*/
|
||||
private function getPaymentExtension(): MockObject
|
||||
{
|
||||
$mockBuilder = $this->getMockBuilder(PaymentExtension::class);
|
||||
$mockBuilder = $this->getMockBuilder(PaymentExtensionInterface::class)
|
||||
->disableOriginalConstructor();
|
||||
try {
|
||||
$mockBuilder->addMethods(['getAgreementIds']);
|
||||
$mockBuilder->addMethods(['getAgreementIds', 'setAgreementIds']);
|
||||
} catch (RuntimeException $e) {
|
||||
// Payment extension already generated.
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class PopupDeliveryDate
|
||||
public function afterFormatDeliveryDateTime(Popup $subject, $result, $date, $time)
|
||||
{
|
||||
if ($this->getCarrier($subject) === Carrier::CODE) {
|
||||
$result = $subject->formatDeliveryDate($date);
|
||||
$result = $subject->formatDeliveryDate($date. ' ' . $time);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -21,9 +21,9 @@ use PHPUnit\Framework\TestCase;
|
||||
*/
|
||||
class PopupDeliveryDateTest extends TestCase
|
||||
{
|
||||
const STUB_CARRIER_CODE_NOT_FEDEX = 'not-fedex';
|
||||
const STUB_DELIVERY_DATE = '2020-02-02';
|
||||
const STUB_DELIVERY_TIME = '12:00';
|
||||
public const STUB_CARRIER_CODE_NOT_FEDEX = 'not-fedex';
|
||||
public const STUB_DELIVERY_DATE = '2020-02-02';
|
||||
public const STUB_DELIVERY_TIME = '12:00';
|
||||
|
||||
/**
|
||||
* @var MockObject|PopupDeliveryDate
|
||||
@@ -68,6 +68,30 @@ class PopupDeliveryDateTest extends TestCase
|
||||
$this->executeOriginalMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the method with Fedex carrier with timezone impact
|
||||
* @dataProvider getDates
|
||||
*/
|
||||
public function testAfterFormatDeliveryDateTimeWithFedexCarrierWithTimezone(
|
||||
$date,
|
||||
$currentTimezone,
|
||||
$convertedTimezone,
|
||||
$expected
|
||||
) {
|
||||
$this->trackingStatusMock->expects($this::once())
|
||||
->method('getCarrier')
|
||||
->willReturn(Carrier::CODE);
|
||||
|
||||
$date = new \DateTime($date, new \DateTimeZone($currentTimezone));
|
||||
$date->setTimezone(new \DateTimeZone($convertedTimezone));
|
||||
$this->subjectMock->expects($this->once())->method('formatDeliveryDate')
|
||||
->willReturn($date->format('Y-m-d'));
|
||||
|
||||
$result = $this->executeOriginalMethodWithTimezone();
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the method with a different carrier
|
||||
*/
|
||||
@@ -119,4 +143,40 @@ class PopupDeliveryDateTest extends TestCase
|
||||
self::STUB_DELIVERY_TIME
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run plugin's original method taking into account timezone
|
||||
*/
|
||||
private function executeOriginalMethodWithTimezone()
|
||||
{
|
||||
return $this->plugin->afterFormatDeliveryDateTime(
|
||||
$this->subjectMock,
|
||||
'Test Result',
|
||||
self::STUB_DELIVERY_DATE,
|
||||
'00:00:00'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testAfterFormatDeliveryDateTimeWithFedexCarrierWithTimezone
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function getDates(): array
|
||||
{
|
||||
return [
|
||||
'same day' => [
|
||||
'date' => '2024-01-07 06:00:00',
|
||||
'current_timezone' => 'US/Eastern',
|
||||
'converted_timezone' => 'America/Chicago',
|
||||
'expected' => '2024-01-07'
|
||||
],
|
||||
'previous day' => [
|
||||
'date' => '2024-01-07 00:00:00',
|
||||
'current_timezone' => 'US/Eastern',
|
||||
'converted_timezone' => 'America/Chicago',
|
||||
'expected' => '2024-01-06'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,18 @@
|
||||
* See COPYING.txt for license details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @codingStandardsIgnoreStart
|
||||
*/
|
||||
|
||||
@import 'source/lib/_lib.less'; // Global lib
|
||||
@import 'source/_theme.less'; // Theme overrides
|
||||
@import 'source/_variables.less'; // Local theme variables
|
||||
|
||||
@baseDir: '../'; // Default
|
||||
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
// Magento/blank
|
||||
.page-print {
|
||||
.logo {
|
||||
@@ -27,7 +33,6 @@
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
// Black prints faster:h5bp.com/s
|
||||
a,
|
||||
a:visited {
|
||||
text-decoration: underline !important;
|
||||
@@ -76,18 +81,18 @@
|
||||
p,
|
||||
h2,
|
||||
h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
.block-content {
|
||||
page-break-before: avoid;
|
||||
break-before: avoid;
|
||||
}
|
||||
|
||||
.block-title,
|
||||
h2,
|
||||
h3 {
|
||||
page-break-after: avoid;
|
||||
break-after: avoid;
|
||||
break-inside: avoid;
|
||||
}
|
||||
|
||||
.nav-toggle {
|
||||
|
||||
@@ -269,12 +269,13 @@ class CategoryRepositoryTest extends WebapiAbstract
|
||||
$this->createdCategories = [$categoryId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @magentoApiDataFixture Magento/Catalog/_files/category.php
|
||||
*/
|
||||
#[
|
||||
DataFixture(CategoryFixture::class, as: 'category')
|
||||
]
|
||||
public function testUpdateWithDefaultSortByAttribute()
|
||||
{
|
||||
$categoryId = 333;
|
||||
$category = $this->fixtures->get('category');
|
||||
$categoryId = $category->getId();
|
||||
$categoryData = [
|
||||
'name' => 'Update Category Test With default_sort_by Attribute',
|
||||
'is_active' => true,
|
||||
@@ -282,7 +283,7 @@ class CategoryRepositoryTest extends WebapiAbstract
|
||||
'custom_attributes' => [
|
||||
[
|
||||
'attribute_code' => 'default_sort_by',
|
||||
'value' => ["name"],
|
||||
'value' => "price"
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -293,7 +294,7 @@ class CategoryRepositoryTest extends WebapiAbstract
|
||||
$category = $model->load($categoryId);
|
||||
$this->assertTrue((bool)$category->getIsActive(), 'Category "is_active" must equal to true');
|
||||
$this->assertEquals("Update Category Test With default_sort_by Attribute", $category->getName());
|
||||
$this->assertEquals("name", $category->getDefaultSortBy());
|
||||
$this->assertEquals("price", $category->getDefaultSortBy());
|
||||
$this->createdCategories = [$categoryId];
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -156,7 +156,7 @@ QUERY;
|
||||
'catalog_product'
|
||||
];
|
||||
$attributeTypes = [
|
||||
'String[]',
|
||||
'String',
|
||||
'String[]',
|
||||
'Int',
|
||||
'CatalogInventoryDataStockItemInterface[]',
|
||||
|
||||
+1
@@ -314,6 +314,7 @@ return [
|
||||
Magento\Catalog\Model\Category\Attribute\Backend\Image\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Attribute\Backend\Startdate\Interceptor::class => null,
|
||||
Magento\Eav\Model\Entity\Attribute\Backend\Datetime\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Attribute\Backend\DefaultSortby\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Attribute\Backend\Sortby\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Category\Attribute\Backend\LayoutUpdate\Interceptor::class => null,
|
||||
Magento\Catalog\Model\Attribute\Backend\Customlayoutupdate\Interceptor::class => null,
|
||||
|
||||
@@ -193,7 +193,7 @@ class TypeLocatorTest extends \PHPUnit\Framework\TestCase
|
||||
'custom_design_to' => 'string',
|
||||
'available_sort_by' => 'string[]',
|
||||
'page_layout' => 'string',
|
||||
'default_sort_by' => 'string[]',
|
||||
'default_sort_by' => 'string',
|
||||
'filter_price_range' => 'double',
|
||||
'custom_layout_update' => 'string',
|
||||
]
|
||||
|
||||
@@ -5,11 +5,24 @@
|
||||
*/
|
||||
namespace Magento\Framework\Model;
|
||||
|
||||
use Exception;
|
||||
use Laminas\Validator\ValidatorChain;
|
||||
use Laminas\Validator\ValidatorInterface;
|
||||
use Magento\Framework\App\CacheInterface;
|
||||
use Magento\Framework\App\ObjectManager;
|
||||
use Magento\Framework\App\State;
|
||||
use Magento\Framework\DataObject;
|
||||
use Magento\Framework\Event\ManagerInterface;
|
||||
use Magento\Framework\Exception\LocalizedException;
|
||||
use Magento\Framework\Message\Error;
|
||||
use Magento\Framework\Model\ActionValidator\RemoveAction;
|
||||
use Magento\Framework\Model\ResourceModel\AbstractResource;
|
||||
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
|
||||
use Magento\Framework\Data\Collection\AbstractDb as AbstractDbCollection;
|
||||
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
|
||||
use Magento\Framework\Phrase;
|
||||
use Magento\Framework\Registry;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Abstract model class
|
||||
@@ -71,12 +84,12 @@ abstract class AbstractModel extends DataObject
|
||||
/**
|
||||
* Resource model instance
|
||||
*
|
||||
* @var \Magento\Framework\Model\ResourceModel\Db\AbstractDb
|
||||
* @var AbstractDb
|
||||
*/
|
||||
protected $_resource;
|
||||
|
||||
/**
|
||||
* @var \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
|
||||
* @var AbstractCollection
|
||||
*/
|
||||
protected $_resourceCollection;
|
||||
|
||||
@@ -129,34 +142,34 @@ abstract class AbstractModel extends DataObject
|
||||
/**
|
||||
* Application Event Dispatcher
|
||||
*
|
||||
* @var \Magento\Framework\Event\ManagerInterface
|
||||
* @var ManagerInterface
|
||||
*/
|
||||
protected $_eventManager;
|
||||
|
||||
/**
|
||||
* Application Cache Manager
|
||||
*
|
||||
* @var \Magento\Framework\App\CacheInterface
|
||||
* @var CacheInterface
|
||||
*/
|
||||
protected $_cacheManager;
|
||||
|
||||
/**
|
||||
* @var \Magento\Framework\Registry
|
||||
* @var Registry
|
||||
*/
|
||||
protected $_registry;
|
||||
|
||||
/**
|
||||
* @var \Psr\Log\LoggerInterface
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $_logger;
|
||||
|
||||
/**
|
||||
* @var \Magento\Framework\App\State
|
||||
* @var State
|
||||
*/
|
||||
protected $_appState;
|
||||
|
||||
/**
|
||||
* @var \Magento\Framework\Model\ActionValidator\RemoveAction
|
||||
* @var RemoveAction
|
||||
*/
|
||||
protected $_actionValidator;
|
||||
|
||||
@@ -168,18 +181,19 @@ abstract class AbstractModel extends DataObject
|
||||
protected $storedData = [];
|
||||
|
||||
/**
|
||||
* @param \Magento\Framework\Model\Context $context
|
||||
* @param \Magento\Framework\Registry $registry
|
||||
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
|
||||
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
|
||||
* @param Context $context
|
||||
* @param Registry $registry
|
||||
* @param AbstractResource|null $resource
|
||||
* @param AbstractDbCollection|null $resourceCollection
|
||||
* @param array $data
|
||||
* @throws LocalizedException
|
||||
*/
|
||||
public function __construct(
|
||||
\Magento\Framework\Model\Context $context,
|
||||
\Magento\Framework\Registry $registry,
|
||||
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
|
||||
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
|
||||
array $data = []
|
||||
Context $context,
|
||||
Registry $registry,
|
||||
AbstractResource $resource = null,
|
||||
AbstractDbCollection $resourceCollection = null,
|
||||
array $data = []
|
||||
) {
|
||||
$this->_registry = $registry;
|
||||
$this->_appState = $context->getAppState();
|
||||
@@ -214,6 +228,7 @@ abstract class AbstractModel extends DataObject
|
||||
*
|
||||
* @param string $resourceModel
|
||||
* @return void
|
||||
* @throws LocalizedException
|
||||
*/
|
||||
protected function _init($resourceModel)
|
||||
{
|
||||
@@ -252,11 +267,11 @@ abstract class AbstractModel extends DataObject
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
|
||||
$this->_registry = $objectManager->get(\Magento\Framework\Registry::class);
|
||||
$objectManager = ObjectManager::getInstance();
|
||||
$this->_registry = $objectManager->get(Registry::class);
|
||||
|
||||
$context = $objectManager->get(\Magento\Framework\Model\Context::class);
|
||||
if ($context instanceof \Magento\Framework\Model\Context) {
|
||||
$context = $objectManager->get(Context::class);
|
||||
if ($context instanceof Context) {
|
||||
$this->_appState = $context->getAppState();
|
||||
$this->_eventManager = $context->getEventDispatcher();
|
||||
$this->_cacheManager = $context->getCacheManager();
|
||||
@@ -357,6 +372,7 @@ abstract class AbstractModel extends DataObject
|
||||
}
|
||||
$this->_data = $key;
|
||||
} else {
|
||||
$this->checkAndConvertNumericValue($key, $value);
|
||||
if (!array_key_exists($key, $this->_data) || $this->_data[$key] !== $value) {
|
||||
$this->_hasDataChanges = true;
|
||||
}
|
||||
@@ -470,19 +486,19 @@ abstract class AbstractModel extends DataObject
|
||||
/**
|
||||
* Get resource instance
|
||||
*
|
||||
* @throws \Magento\Framework\Exception\LocalizedException
|
||||
* @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb
|
||||
* @return AbstractDb
|
||||
* @throws LocalizedException
|
||||
* @deprecated 101.0.0 because resource models should be used directly
|
||||
* @see we don't recommend this approach anymore
|
||||
*/
|
||||
protected function _getResource()
|
||||
{
|
||||
if (empty($this->_resourceName) && empty($this->_resource)) {
|
||||
throw new \Magento\Framework\Exception\LocalizedException(
|
||||
new \Magento\Framework\Phrase('The resource isn\'t set.')
|
||||
throw new LocalizedException(
|
||||
new Phrase('The resource isn\'t set.')
|
||||
);
|
||||
}
|
||||
return $this->_resource ?: \Magento\Framework\App\ObjectManager::getInstance()->get($this->_resourceName);
|
||||
return $this->_resource ?: ObjectManager::getInstance()->get($this->_resourceName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -499,20 +515,20 @@ abstract class AbstractModel extends DataObject
|
||||
* Get collection instance
|
||||
*
|
||||
* @TODO MAGETWO-23541: Incorrect dependencies between Model\AbstractModel and Data\Collection\Db from Framework
|
||||
* @throws \Magento\Framework\Exception\LocalizedException
|
||||
* @return \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
|
||||
* @throws LocalizedException
|
||||
* @return AbstractCollection
|
||||
* @deprecated 101.0.0 because collections should be used directly via factory
|
||||
* @see we don't recommend this approach anymore
|
||||
*/
|
||||
public function getResourceCollection()
|
||||
{
|
||||
if (empty($this->_resourceCollection) && empty($this->_collectionName)) {
|
||||
throw new \Magento\Framework\Exception\LocalizedException(
|
||||
new \Magento\Framework\Phrase('Model collection resource name is not defined.')
|
||||
throw new LocalizedException(
|
||||
new Phrase('Model collection resource name is not defined.')
|
||||
);
|
||||
}
|
||||
return !$this->_collectionName ? clone $this
|
||||
->_resourceCollection : \Magento\Framework\App\ObjectManager::getInstance()
|
||||
->_resourceCollection : ObjectManager::getInstance()
|
||||
->create(
|
||||
$this->_collectionName
|
||||
);
|
||||
@@ -522,9 +538,10 @@ abstract class AbstractModel extends DataObject
|
||||
* Retrieve collection instance
|
||||
*
|
||||
* @TODO MAGETWO-23541: Incorrect dependencies between Model\AbstractModel and Data\Collection\Db from Framework
|
||||
* @return \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
|
||||
* @deprecated 101.0.0 because collections should be used directly via factory
|
||||
* @return AbstractCollection
|
||||
* @throws LocalizedException
|
||||
* @see we don't recommend this approach anymore
|
||||
* @deprecated 101.0.0 because collections should be used directly via factory
|
||||
*/
|
||||
public function getCollection()
|
||||
{
|
||||
@@ -537,10 +554,11 @@ abstract class AbstractModel extends DataObject
|
||||
* @param integer $modelId
|
||||
* @param null|string $field
|
||||
* @return $this
|
||||
* @throws LocalizedException
|
||||
* @see we don't recommend this approach anymore
|
||||
* @deprecated 100.1.0 because entities must not be responsible for their own loading.
|
||||
* Service contracts should persist entities. Use resource model "load" or collections to implement
|
||||
* service contract model loading operations.
|
||||
* @see we don't recommend this approach anymore
|
||||
*/
|
||||
public function load($modelId, $field = null)
|
||||
{
|
||||
@@ -651,7 +669,7 @@ abstract class AbstractModel extends DataObject
|
||||
* Save object data
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
* @throws Exception
|
||||
*
|
||||
* @deprecated 100.1.0 because entities must not be responsible for their own persistence.
|
||||
* Service contracts should persist entities. Use resource model "save" to implement
|
||||
@@ -726,7 +744,7 @@ abstract class AbstractModel extends DataObject
|
||||
new Phrase(implode(PHP_EOL, $errors))
|
||||
);
|
||||
foreach ($errors as $errorMessage) {
|
||||
$exception->addMessage(new \Magento\Framework\Message\Error($errorMessage));
|
||||
$exception->addMessage(new Error($errorMessage));
|
||||
}
|
||||
throw $exception;
|
||||
}
|
||||
@@ -739,6 +757,7 @@ abstract class AbstractModel extends DataObject
|
||||
* Returns FALSE, if no validation rules exist.
|
||||
*
|
||||
* @return ValidatorInterface|false
|
||||
* @throws LocalizedException
|
||||
*/
|
||||
protected function _getValidatorBeforeSave()
|
||||
{
|
||||
@@ -782,7 +801,7 @@ abstract class AbstractModel extends DataObject
|
||||
*/
|
||||
private function getValidator(): ValidatorChain
|
||||
{
|
||||
return \Magento\Framework\App\ObjectManager::getInstance()->create(ValidatorChain::class);
|
||||
return ObjectManager::getInstance()->create(ValidatorChain::class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -852,7 +871,7 @@ abstract class AbstractModel extends DataObject
|
||||
* Delete object from database
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
* @throws Exception
|
||||
* @deprecated 100.1.0 because entities must not be responsible for their own deletion.
|
||||
* Service contracts should delete entities. Use resource model "delete" method to implement
|
||||
* service contract persistence operations.
|
||||
@@ -868,13 +887,13 @@ abstract class AbstractModel extends DataObject
|
||||
* Processing object before delete data
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Magento\Framework\Exception\LocalizedException
|
||||
* @throws LocalizedException
|
||||
*/
|
||||
public function beforeDelete()
|
||||
{
|
||||
if (!$this->_actionValidator->isAllowed($this)) {
|
||||
throw new \Magento\Framework\Exception\LocalizedException(
|
||||
new \Magento\Framework\Phrase('Delete operation is forbidden for current area')
|
||||
throw new LocalizedException(
|
||||
new Phrase('Delete operation is forbidden for current area')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -913,7 +932,7 @@ abstract class AbstractModel extends DataObject
|
||||
/**
|
||||
* Retrieve model resource
|
||||
*
|
||||
* @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb
|
||||
* @return AbstractDb
|
||||
* @deprecated 101.0.0 because resource models should be used directly
|
||||
* @see we don't recommend this approach anymore
|
||||
*/
|
||||
@@ -1010,4 +1029,24 @@ abstract class AbstractModel extends DataObject
|
||||
{
|
||||
return $this->_eventPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and Convert Numeric Value for Proper Type Matching
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
private function checkAndConvertNumericValue(mixed $key, mixed $value): void
|
||||
{
|
||||
if (array_key_exists($key, $this->_data) && is_numeric($this->_data[$key])
|
||||
&& $value != null
|
||||
) {
|
||||
if (is_int($value)) {
|
||||
$this->_data[$key] = (int) $this->_data[$key];
|
||||
} elseif (is_float($value)) {
|
||||
$this->_data[$key] = (float) $this->_data[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,4 +190,49 @@ class AbstractModelTest extends TestCase
|
||||
$this->model->setDataChanges(true);
|
||||
$this->assertTrue($this->model->hasDataChanges());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case for checking setData function is working for all possible key value pairs
|
||||
*
|
||||
* @dataProvider getKeyValueDataPairs
|
||||
*/
|
||||
public function testSetDataWithDifferentKeyValuePairs(
|
||||
array $data,
|
||||
mixed $testKey,
|
||||
mixed $testValue,
|
||||
bool $hasDataChangedFor
|
||||
): void {
|
||||
$this->model->setData($data);
|
||||
$this->model->setOrigData();
|
||||
$this->model->setData($testKey, $testValue);
|
||||
$this->assertEquals($data, $this->model->getOrigData());
|
||||
$this->assertEquals($hasDataChangedFor, $this->model->dataHasChangedFor($testKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testSetDataWithDifferentKeyValuePairs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getKeyValueDataPairs(): array
|
||||
{
|
||||
return [
|
||||
'when test data and compare data are string' => [['key' => 'value'], 'key', 'value', false],
|
||||
'when test data and compare data are different' => [['key' => 'value'], 'key', 10, true],
|
||||
'when test data string and compare data is null' => [['key' => 'value'], 'key', null, true],
|
||||
'when test data and compare data both null' => [['key' => null], 'key', null, false],
|
||||
'when test data empty string and compare data is null' => [['key' => ''], 'key', null, false],
|
||||
'when test data and compare data are empty string' => [['key' => ''], 'key', '', false],
|
||||
'when test data is null and compare data is empty string' => [['key' => null], 'key', '', false],
|
||||
'when test data and compare data are int' => [['key' => 1], 'key', 1, false],
|
||||
'when test data is int and compare data is float' => [['key' => 1.0], 'key', 1, false],
|
||||
'when test data is string and compare data is float' => [['key' => '1.0'], 'key', 1.0, false],
|
||||
'when test data is string and compare data is int' => [['key' => '1'], 'key', 1, false],
|
||||
'when test data is float and compare data is string' => [['key' => 1.0], 'key', '1.0', false],
|
||||
'when test data is int and compare data is string' => [['key' => 1], 'key', '1', false],
|
||||
'when test data and compare data are float' => [['key' => 1.0], 'key', 1.0, false],
|
||||
'when test data is 0 and compare data is null' => [['key' => 0], 'key', null, false],
|
||||
'when test data is null and compare data is 0' => [['key' => null], 'key', 0, false],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user