Skip to content

Commit d869864

Browse files
committed
Merge branch '2.4-develop' into MC-42249
2 parents c5a7da9 + 3c5ff49 commit d869864

File tree

198 files changed

+8936
-6007
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

198 files changed

+8936
-6007
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"Allow Adobe to collect usage data to improve user experience and offer in-product guidance", "Allow Adobe to collect usage data to improve user experience and offer in-product guidance"
2+
"<p>By clicking on <b>Allow</b>, you agree that we may collect anonymous usage data from you to:</p> <ol class=""modal-list""> <li>Help us improve the Magento Admin user experience</li> <li>Provide interactive in-product guidance, such as technical support and tips to improve utilization of the product from within the Admin UI. This may include notifications of new features, product support/guidance, onboarding information, tooltips, and more.</li> </ol> <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin UI and related products and services.</p> <p>You can learn more and opt-out at any time by following the instructions in <a href=""https://docs.magento.com/user-guide/configuration/advanced/admin.html#admin-usage"">merchant documentation</a>.</p>", "<p>By clicking on <b>Allow</b>, you agree that we may collect anonymous usage data from you to:</p> <ol class=""modal-list""> <li>Help us improve the Magento Admin user experience</li> <li>Provide interactive in-product guidance, such as technical support and tips to improve utilization of the product from within the Admin UI. This may include notifications of new features, product support/guidance, onboarding information, tooltips, and more.</li> </ol> <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin UI and related products and services.</p> <p>You can learn more and opt-out at any time by following the instructions in <a href=""https://docs.magento.com/user-guide/configuration/advanced/admin.html#admin-usage"">merchant documentation</a>.</p>"
3+

app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@
1919
</block>
2020
</referenceContainer>
2121
</body>
22-
</page>
22+
</page>

app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
<state>true</state>
5050
<options>
5151
<option name="modalClass" xsi:type="string">admin-usage-notification</option>
52-
<option name="title" xsi:type="string" translate="true">Allow admin usage data collection</option>
52+
<option name="title" xsi:type="string" translate="true">Allow Adobe to collect usage data to improve user experience and offer in-product guidance</option>
5353
<option name="autoOpen" xsi:type="boolean">true</option>
5454
<option name="type" xsi:type="string">popup</option>
5555
<option name="clickableOverlay" xsi:type="boolean">false</option>
@@ -82,11 +82,7 @@
8282
<item name="config" xsi:type="array">
8383
<item name="label" xsi:type="string"/>
8484
<item name="additionalClasses" xsi:type="string">release-notification-text</item>
85-
<item name="text" xsi:type="string" translate="true"><![CDATA[
86-
<p>Help us improve Magento Admin by allowing us to collect usage data.</p>
87-
<p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p>
88-
<p>You can learn more and opt out at any time by following the instructions in <a href="https://docs.magento.com/user-guide/stores/admin.html" target="_blank" tabindex="0">merchant documentation</a>.</p>
89-
]]></item>
85+
<item name="text" xsi:type="string" translate="true"><![CDATA[<p>By clicking on <b>Allow</b>, you agree that we may collect anonymous usage data from you to:</p> <ol class="modal-list"> <li>Help us improve the Magento Admin user experience</li> <li>Provide interactive in-product guidance, such as technical support and tips to improve utilization of the product from within the Admin UI. This may include notifications of new features, product support/guidance, onboarding information, tooltips, and more.</li> </ol> <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin UI and related products and services.</p> <p>You can learn more and opt-out at any time by following the instructions in <a href="https://docs.magento.com/user-guide/configuration/advanced/admin.html#admin-usage">merchant documentation</a>.</p>]]></item>
9086
</item>
9187
</argument>
9288
</container>

app/code/Magento/AdminNotification/view/adminhtml/web/system/notification.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ define([
5252
tmpl = $(tmpl);
5353

5454
this.element.html(
55-
$('<ul />', {
55+
$('<ul></ul>', {
5656
'class': 'message-system-list'
5757
}).append(tmpl)
5858
).trigger('contentUpdated');

app/code/Magento/Backend/Block/Store/Switcher.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace Magento\Backend\Block\Store;
99

10+
use Magento\Framework\Exception\LocalizedException;
11+
1012
/**
1113
* Store switcher block
1214
*
@@ -471,9 +473,17 @@ public function getCurrentSelectionName()
471473
*/
472474
public function getCurrentWebsiteName()
473475
{
474-
if ($this->getWebsiteId() !== null) {
476+
$websiteId = $this->getWebsiteId();
477+
if ($websiteId !== null) {
478+
if ($this->hasData('get_data_from_request')) {
479+
$requestedWebsite = $this->getRequest()->getParams('website');
480+
if (!empty($requestedWebsite)
481+
&& array_key_exists('website', $requestedWebsite)) {
482+
$websiteId = $requestedWebsite['website'];
483+
}
484+
}
475485
$website = $this->_websiteFactory->create();
476-
$website->load($this->getWebsiteId());
486+
$website->load($websiteId);
477487
if ($website->getId()) {
478488
return $website->getName();
479489
}
@@ -504,12 +514,21 @@ public function getCurrentStoreGroupName()
504514
* Get current store view name
505515
*
506516
* @return string
517+
* @throws LocalizedException
507518
*/
508519
public function getCurrentStoreName()
509520
{
510-
if ($this->getStoreId() !== null) {
521+
$storeId = $this->getStoreId();
522+
if ($storeId !== null) {
523+
if ($this->hasData('get_data_from_request')) {
524+
$requestedStore = $this->getRequest()->getParams('store');
525+
if (!empty($requestedStore)
526+
&& array_key_exists('store', $requestedStore)) {
527+
$storeId = $requestedStore['store'];
528+
}
529+
}
511530
$store = $this->_storeFactory->create();
512-
$store->load($this->getStoreId());
531+
$store->load($storeId);
513532
if ($store->getId()) {
514533
return $store->getName();
515534
}

app/code/Magento/Backend/Test/Unit/Block/Store/SwitcherTest.php

Lines changed: 155 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@
88
namespace Magento\Backend\Test\Unit\Block\Store;
99

1010
use Magento\Backend\Block\Store\Switcher;
11+
use Magento\Framework\App\RequestInterface;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Store\Model\StoreFactory;
14+
use Magento\Store\Model\Store;
15+
use Magento\Store\Model\WebsiteFactory;
16+
use Magento\Store\Model\Website;
1117
use Magento\Backend\Block\Template\Context;
1218
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1319
use Magento\Store\Model\StoreManagerInterface;
14-
use Magento\Store\Model\Website;
1520
use PHPUnit\Framework\TestCase;
1621

1722
class SwitcherTest extends TestCase
@@ -23,20 +28,81 @@ class SwitcherTest extends TestCase
2328

2429
private $storeManagerMock;
2530

31+
/**
32+
* @var RequestInterface|MockObject
33+
*/
34+
private $requestMock;
35+
36+
/**
37+
* @var WebsiteFactory|MockObject
38+
*/
39+
private $websiteFactoryMock;
40+
41+
/**
42+
* @var StoreFactory|MockObject
43+
*/
44+
private $storeFactoryMock;
45+
46+
/**
47+
* @var Website|MockObject
48+
*/
49+
private $websiteMock;
50+
51+
/**
52+
* @var Store|MockObject
53+
*/
54+
private $storeMock;
55+
2656
protected function setUp(): void
2757
{
2858
$this->storeManagerMock = $this->getMockForAbstractClass(StoreManagerInterface::class);
2959
$objectHelper = new ObjectManager($this);
60+
$this->requestMock = $this->getMockBuilder(RequestInterface::class)
61+
->getMockForAbstractClass();
62+
$this->websiteFactoryMock = $this->getMockBuilder(WebsiteFactory::class)
63+
->disableOriginalConstructor()
64+
->setMethods(['create'])
65+
->getMock();
66+
$this->storeFactoryMock = $this->getMockBuilder(StoreFactory::class)
67+
->disableOriginalConstructor()
68+
->setMethods(['create'])
69+
->getMock();
70+
$this->websiteMock = $this->getMockBuilder(Website::class)
71+
->disableOriginalConstructor()
72+
->setMethods(['load', 'getId', 'getName'])
73+
->getMock();
74+
$this->storeMock = $this->getMockBuilder(Store::class)
75+
->disableOriginalConstructor()
76+
->setMethods(['load', 'getId', 'getName'])
77+
->getMock();
78+
$this->websiteFactoryMock->expects($this->any())
79+
->method('create')
80+
->willReturn($this->websiteMock);
81+
$this->storeFactoryMock->expects($this->any())
82+
->method('create')
83+
->willReturn($this->storeMock);
84+
$this->websiteMock->expects($this->any())
85+
->method('load')
86+
->willReturnSelf();
87+
$this->storeMock->expects($this->any())
88+
->method('load')
89+
->willReturnSelf();
3090
$context = $objectHelper->getObject(
3191
Context::class,
3292
[
3393
'storeManager' => $this->storeManagerMock,
94+
'request' => $this->requestMock
3495
]
3596
);
3697

3798
$this->switcherBlock = $objectHelper->getObject(
3899
Switcher::class,
39-
['context' => $context]
100+
[
101+
'context' => $context,
102+
'data' => ['get_data_from_request' => 1],
103+
'websiteFactory' => $this->websiteFactoryMock,
104+
'storeFactory' => $this->storeFactoryMock
105+
]
40106
);
41107
}
42108

@@ -58,4 +124,91 @@ public function testGetWebsitesIfSetWebsiteIds()
58124
$expected = [1 => $websiteMock];
59125
$this->assertEquals($expected, $this->switcherBlock->getWebsites());
60126
}
127+
128+
/**
129+
* Test case for after current store name plugin
130+
*
131+
* @param array $requestedStore
132+
* @param string $expectedResult
133+
* @return void
134+
* @dataProvider getStoreNameDataProvider
135+
* @throws LocalizedException
136+
*/
137+
public function testAfterGetCurrentStoreName(array $requestedStore, string $expectedResult): void
138+
{
139+
$this->requestMock->expects($this->any())
140+
->method('getParams')
141+
->willReturn($requestedStore);
142+
$this->storeMock->expects($this->any())
143+
->method('getId')
144+
->willReturn($requestedStore);
145+
$this->storeMock->expects($this->any())
146+
->method('getName')
147+
->willReturn($expectedResult);
148+
$this->assertSame($expectedResult, $this->switcherBlock->getCurrentStoreName());
149+
}
150+
151+
/**
152+
* Data provider for getStoreName plugin
153+
*
154+
* @return array
155+
*/
156+
public function getStoreNameDataProvider(): array
157+
{
158+
return [
159+
'test storeName with valid requested store' =>
160+
[
161+
['store' => 'test store'],
162+
'base store'
163+
],
164+
'test storeName with invalid requested store' =>
165+
[
166+
['store' => 'test store'],
167+
'test store'
168+
]
169+
];
170+
}
171+
172+
/**
173+
* Test case for get current website name
174+
*
175+
* @param array $requestedWebsite
176+
* @param string $expectedResult
177+
* @return void
178+
* @dataProvider getWebsiteNameDataProvider
179+
*/
180+
public function testGetCurrentWebsiteName(array $requestedWebsite, string $expectedResult): void
181+
{
182+
$this->requestMock->expects($this->any())
183+
->method('getParams')
184+
->willReturn($requestedWebsite);
185+
$this->websiteMock->expects($this->any())
186+
->method('getId')
187+
->willReturn($requestedWebsite);
188+
$this->websiteMock->expects($this->any())
189+
->method('getName')
190+
->willReturn($expectedResult);
191+
$this->assertSame($expectedResult, $this->switcherBlock->getCurrentWebsiteName());
192+
}
193+
194+
/**
195+
* Data provider for getWebsiteName plugin
196+
*
197+
* @return array
198+
*/
199+
public function getWebsiteNameDataProvider(): array
200+
{
201+
return [
202+
'test websiteName with valid requested website' =>
203+
[
204+
['website' => 'test website'],
205+
'base website'
206+
],
207+
'test websiteName with invalid requested website' =>
208+
[
209+
['website' => 'test website'],
210+
'test website'
211+
]
212+
];
213+
}
61214
}

app/code/Magento/Catalog/Model/Product/Copier.php

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
namespace Magento\Catalog\Model\Product;
77

88
use Magento\Catalog\Api\Data\ProductInterface;
9+
use Magento\Catalog\Api\ProductRepositoryInterface;
910
use Magento\Catalog\Model\Attribute\ScopeOverriddenValue;
1011
use Magento\Catalog\Model\Product;
1112
use Magento\Catalog\Model\Product\Attribute\Source\Status;
1213
use Magento\Catalog\Model\Product\Option\Repository as OptionRepository;
1314
use Magento\Catalog\Model\ProductFactory;
14-
use Magento\Framework\App\ObjectManager;
15+
use Magento\Catalog\Model\ResourceModel\DuplicatedProductAttributesCopier;
1516
use Magento\Framework\EntityManager\MetadataPool;
1617
use Magento\Store\Model\Store;
1718
use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException;
@@ -50,25 +51,41 @@ class Copier
5051
*/
5152
private $scopeOverriddenValue;
5253

54+
/**
55+
* @var ProductRepositoryInterface
56+
*/
57+
private $productRepository;
58+
59+
/**
60+
* @var DuplicatedProductAttributesCopier
61+
*/
62+
private $attributeCopier;
63+
5364
/**
5465
* @param CopyConstructorInterface $copyConstructor
5566
* @param ProductFactory $productFactory
5667
* @param ScopeOverriddenValue $scopeOverriddenValue
5768
* @param OptionRepository|null $optionRepository
5869
* @param MetadataPool|null $metadataPool
70+
* @param ProductRepositoryInterface $productRepository
71+
* @param DuplicatedProductAttributesCopier $attributeCopier
5972
*/
6073
public function __construct(
6174
CopyConstructorInterface $copyConstructor,
6275
ProductFactory $productFactory,
6376
ScopeOverriddenValue $scopeOverriddenValue,
6477
OptionRepository $optionRepository,
65-
MetadataPool $metadataPool
78+
MetadataPool $metadataPool,
79+
ProductRepositoryInterface $productRepository,
80+
DuplicatedProductAttributesCopier $attributeCopier
6681
) {
6782
$this->productFactory = $productFactory;
6883
$this->copyConstructor = $copyConstructor;
6984
$this->scopeOverriddenValue = $scopeOverriddenValue;
7085
$this->optionRepository = $optionRepository;
7186
$this->metadataPool = $metadataPool;
87+
$this->productRepository = $productRepository;
88+
$this->attributeCopier = $attributeCopier;
7289
}
7390

7491
/**
@@ -79,11 +96,13 @@ public function __construct(
7996
*/
8097
public function copy(Product $product): Product
8198
{
82-
$product->getWebsiteIds();
83-
$product->getCategoryIds();
84-
8599
$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
86100

101+
/* Regardless in what scope the product was provided,
102+
for duplicating we want to clone product in Global scope first */
103+
if ((int)$product->getStoreId() !== Store::DEFAULT_STORE_ID) {
104+
$product = $this->productRepository->getById($product->getId(), true, Store::DEFAULT_STORE_ID);
105+
}
87106
/** @var Product $duplicate */
88107
$duplicate = $this->productFactory->create();
89108
$productData = $product->getData();
@@ -102,6 +121,7 @@ public function copy(Product $product): Product
102121
$duplicate->setStoreId(Store::DEFAULT_STORE_ID);
103122
$this->copyConstructor->build($product, $duplicate);
104123
$this->setDefaultUrl($product, $duplicate);
124+
$this->attributeCopier->copyProductAttributes($product, $duplicate);
105125
$this->setStoresUrl($product, $duplicate);
106126
$this->optionRepository->duplicate($product, $duplicate);
107127

0 commit comments

Comments
 (0)