Skip to content

Commit d2cc95b

Browse files
authored
Merge branch '2.4-develop' into jquery-upgrade
2 parents 5b0c1ab + e585f82 commit d2cc95b

File tree

26 files changed

+896
-213
lines changed

26 files changed

+896
-213
lines changed

app/code/Magento/CatalogUrlRewrite/Model/Category/Plugin/Store/View.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,10 @@ public function afterSave(
104104
Store $object,
105105
Store $store
106106
): Store {
107-
if ($this->origStore->isObjectNew() || $this->origStore->dataHasChangedFor('group_id')) {
107+
if (
108+
$this->origStore->getData('group_id')
109+
&& ($this->origStore->isObjectNew() || $this->origStore->dataHasChangedFor('group_id'))
110+
) {
108111
$categoryRewriteUrls = $this->generateCategoryUrls(
109112
(int)$this->origStore->getRootCategoryId(),
110113
(int)$this->origStore->getId()

app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/Plugin/Store/ViewTest.php

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@
77

88
namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category\Plugin\Store;
99

10-
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
1110
use Magento\Catalog\Model\Category;
1211
use Magento\Catalog\Model\CategoryFactory;
1312
use Magento\Catalog\Model\Product;
1413
use Magento\Catalog\Model\ProductFactory;
14+
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
1515
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
1616
use Magento\CatalogUrlRewrite\Model\Category\Plugin\Store\View as StoreViewPlugin;
1717
use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
1818
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
1919
use Magento\Framework\Model\AbstractModel;
20-
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
21-
use Magento\Store\Model\ResourceModel\Store;
20+
use Magento\Store\Model\ResourceModel\Store as StoreResourceModel;
21+
use Magento\Store\Model\Store;
2222
use Magento\UrlRewrite\Model\UrlPersistInterface;
2323
use PHPUnit\Framework\MockObject\MockObject;
2424
use PHPUnit\Framework\TestCase;
@@ -28,11 +28,6 @@
2828
*/
2929
class ViewTest extends TestCase
3030
{
31-
/**
32-
* @var ObjectManager
33-
*/
34-
private $objectManager;
35-
3631
/**
3732
* @var StoreViewPlugin
3833
*/
@@ -44,7 +39,7 @@ class ViewTest extends TestCase
4439
private $abstractModelMock;
4540

4641
/**
47-
* @var Store|MockObject
42+
* @var StoreResourceModel|MockObject
4843
*/
4944
private $subjectMock;
5045

@@ -93,12 +88,11 @@ class ViewTest extends TestCase
9388
*/
9489
protected function setUp(): void
9590
{
96-
$this->objectManager = new ObjectManager($this);
9791
$this->abstractModelMock = $this->getMockBuilder(AbstractModel::class)
9892
->disableOriginalConstructor()
9993
->setMethods(['isObjectNew'])
10094
->getMockForAbstractClass();
101-
$this->subjectMock = $this->getMockBuilder(Store::class)
95+
$this->subjectMock = $this->getMockBuilder(StoreResourceModel::class)
10296
->disableOriginalConstructor()
10397
->getMock();
10498
$this->urlPersistMock = $this->getMockBuilder(UrlPersistInterface::class)
@@ -131,15 +125,12 @@ protected function setUp(): void
131125
->disableOriginalConstructor()
132126
->setMethods(['getCollection'])
133127
->getMock();
134-
$this->plugin = $this->objectManager->getObject(
135-
StoreViewPlugin::class,
136-
[
137-
'urlPersist' => $this->urlPersistMock,
138-
'categoryFactory' => $this->categoryFactoryMock,
139-
'productFactory' => $this->productFactoryMock,
140-
'categoryUrlRewriteGenerator' => $this->categoryUrlRewriteGeneratorMock,
141-
'productUrlRewriteGenerator' => $this->productUrlRewriteGeneratorMock
142-
]
128+
$this->plugin = new StoreViewPlugin(
129+
$this->urlPersistMock,
130+
$this->categoryFactoryMock,
131+
$this->productFactoryMock,
132+
$this->categoryUrlRewriteGeneratorMock,
133+
$this->productUrlRewriteGeneratorMock
143134
);
144135
}
145136

@@ -150,13 +141,19 @@ protected function setUp(): void
150141
*/
151142
public function testAfterSave(): void
152143
{
153-
$origStoreMock = $this->getMockBuilder(\Magento\Store\Model\Store::class)
144+
$origStoreMock = $this->getMockBuilder(Store::class)
154145
->disableOriginalConstructor()
155146
->getMock();
156147
$reflectionStore = new \ReflectionClass($this->plugin);
157148
$origStore = $reflectionStore->getProperty('origStore');
158149
$origStore->setAccessible(true);
159150
$origStore->setValue($this->plugin, $origStoreMock);
151+
152+
$origStoreMock->expects($this->atLeastOnce())
153+
->method('getData')
154+
->with('group_id')
155+
->willReturn('1');
156+
160157
$origStoreMock->expects($this->atLeastOnce())
161158
->method('isObjectNew')
162159
->willReturn(true);
@@ -203,7 +200,54 @@ public function testAfterSave(): void
203200

204201
$this->assertSame(
205202
$this->subjectMock,
206-
$this->plugin->afterSave($this->subjectMock, $this->subjectMock, $this->abstractModelMock)
203+
$this->plugin->afterSave($this->subjectMock, $this->subjectMock)
204+
);
205+
}
206+
207+
public function testAfterSaveWhenNoGroupId()
208+
{
209+
$origStoreMock = $this->getMockBuilder(Store::class)
210+
->disableOriginalConstructor()
211+
->getMock();
212+
$reflectionStore = new \ReflectionClass($this->plugin);
213+
$origStore = $reflectionStore->getProperty('origStore');
214+
$origStore->setAccessible(true);
215+
$origStore->setValue($this->plugin, $origStoreMock);
216+
217+
$origStoreMock->expects($this->atLeastOnce())
218+
->method('getData')
219+
->with('group_id')
220+
->willReturn(null);
221+
222+
$origStoreMock->expects($this->any())
223+
->method('isObjectNew')
224+
->willReturn(true);
225+
226+
$this->abstractModelMock->expects($this->any())
227+
->method('isObjectNew')
228+
->willReturn(true);
229+
$categoryCollection = $this->getMockBuilder(CategoryCollection::class)
230+
->disableOriginalConstructor()
231+
->setMethods(['getIterator'])
232+
->getMock();
233+
$categoryCollection->expects($this->any())
234+
->method('getIterator')
235+
->willReturn(new \ArrayIterator([]));
236+
$this->categoryMock->expects($this->never())
237+
->method('getCategories');
238+
$this->categoryFactoryMock->expects($this->never())->method('create');
239+
$this->productFactoryMock->expects($this->never())->method('create');
240+
$this->productMock->expects($this->never())->method('getCollection');
241+
$this->productCollectionMock->expects($this->never())->method('addCategoryIds');
242+
$this->productCollectionMock->expects($this->never())->method('addAttributeToSelect');
243+
$this->productCollectionMock->expects($this->never())->method('addStoreFilter');
244+
245+
$this->productCollectionMock->expects($this->never())->method('getIterator');
246+
$this->productUrlRewriteGeneratorMock->expects($this->never())->method('generate');
247+
248+
$this->assertSame(
249+
$this->subjectMock,
250+
$this->plugin->afterSave($this->subjectMock, $this->subjectMock)
207251
);
208252
}
209253

app/code/Magento/Cms/etc/db_schema.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
<constraint xsi:type="primary" referenceId="PRIMARY">
2323
<column name="block_id"/>
2424
</constraint>
25+
<index referenceId="CMS_BLOCK_IDENTIFIER" indexType="btree">
26+
<column name="identifier"/>
27+
</index>
2528
<index referenceId="CMS_BLOCK_TITLE_IDENTIFIER_CONTENT" indexType="fulltext">
2629
<column name="title"/>
2730
<column name="identifier"/>

app/code/Magento/Cms/etc/db_schema_whitelist.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"is_active": true
1111
},
1212
"index": {
13-
"CMS_BLOCK_TITLE_IDENTIFIER_CONTENT": true
13+
"CMS_BLOCK_TITLE_IDENTIFIER_CONTENT": true,
14+
"CMS_BLOCK_IDENTIFIER": true
1415
},
1516
"constraint": {
1617
"PRIMARY": true
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CmsUrlRewrite\Plugin\Cms\Model\PageRepository;
9+
10+
use Magento\Cms\Api\Data\PageInterface;
11+
use Magento\Cms\Model\PageRepository\ValidationComposite;
12+
use Magento\CmsUrlRewrite\Model\CmsPageUrlPathGenerator;
13+
14+
/**
15+
* Generate url_key if the merchant didn't fill this field
16+
*/
17+
class ValidationCompositePlugin
18+
{
19+
/**
20+
* @var CmsPageUrlPathGenerator
21+
*/
22+
private $cmsPageUrlPathGenerator;
23+
24+
/**
25+
* @param CmsPageUrlPathGenerator $cmsPageUrlPathGenerator
26+
*/
27+
public function __construct(
28+
CmsPageUrlPathGenerator $cmsPageUrlPathGenerator
29+
) {
30+
$this->cmsPageUrlPathGenerator = $cmsPageUrlPathGenerator;
31+
}
32+
33+
/**
34+
* Before save handler
35+
*
36+
* @param ValidationComposite $subject
37+
* @param PageInterface $page
38+
*/
39+
public function beforeSave(
40+
ValidationComposite $subject,
41+
PageInterface $page
42+
) {
43+
$urlKey = $page->getData('identifier');
44+
if ($urlKey === '' || $urlKey === null) {
45+
$page->setData('identifier', $this->cmsPageUrlPathGenerator->generateUrlKey($page));
46+
}
47+
}
48+
}

app/code/Magento/CmsUrlRewrite/etc/di.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
<type name="Magento\Cms\Model\ResourceModel\Page">
1010
<plugin name="cms_url_rewrite_plugin" type="Magento\CmsUrlRewrite\Plugin\Cms\Model\ResourceModel\Page"/>
1111
</type>
12+
<type name="Magento\Cms\Model\PageRepository\ValidationComposite">
13+
<plugin name="cms_validate_url_plugin"
14+
type="Magento\CmsUrlRewrite\Plugin\Cms\Model\PageRepository\ValidationCompositePlugin" sortOrder="10"/>
15+
</type>
1216
<type name="Magento\UrlRewrite\Model\UrlRewrite">
1317
<arguments>
1418
<argument name="entityToCacheTagMap" xsi:type="array">

app/code/Magento/Customer/view/frontend/web/js/customer-data.js

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ define([
1717
], function ($, _, ko, sectionConfig, url) {
1818
'use strict';
1919

20-
var options = {},
20+
var options = {
21+
cookieLifeTime: 86400 //1 day by default
22+
},
2123
storage,
2224
storageInvalidation,
2325
invalidateCacheBySessionTimeOut,
@@ -30,6 +32,22 @@ define([
3032
url.setBaseUrl(window.BASE_URL);
3133
options.sectionLoadUrl = url.build('customer/section/load');
3234

35+
/**
36+
* Storage initialization
37+
*/
38+
function initStorage() {
39+
$.cookieStorage.setConf({
40+
path: '/',
41+
expires: new Date(Date.now() + parseInt(options.cookieLifeTime, 10) * 1000),
42+
samesite: 'lax'
43+
});
44+
storage = $.initNamespaceStorage('mage-cache-storage').localStorage;
45+
storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage;
46+
}
47+
48+
// Initialize storage with default parameters to prevent JS errors while component still not initialized
49+
initStorage();
50+
3351
/**
3452
* @param {Object} invalidateOptions
3553
*/
@@ -216,15 +234,7 @@ define([
216234
/**
217235
* Storage init
218236
*/
219-
initStorage: function () {
220-
$.cookieStorage.setConf({
221-
path: '/',
222-
expires: new Date(Date.now() + parseInt(options.cookieLifeTime, 10) * 1000),
223-
samesite: 'lax'
224-
});
225-
storage = $.initNamespaceStorage('mage-cache-storage').localStorage;
226-
storageInvalidation = $.initNamespaceStorage('mage-cache-storage-section-invalidation').localStorage;
227-
},
237+
initStorage: initStorage,
228238

229239
/**
230240
* Retrieve the list of sections that has expired since last page reload.
@@ -389,7 +399,10 @@ define([
389399
*/
390400
'Magento_Customer/js/customer-data': function (settings) {
391401
options = settings;
402+
403+
// re-init storage with a new settings
392404
customerData.initStorage();
405+
393406
invalidateCacheBySessionTimeOut(settings);
394407
invalidateCacheByCloseCookieSession();
395408
customerData.init();
Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,85 @@
1-
Magento_ImportExport module provides a framework and basic functionality for importing/exporting various entities in Magento.
1+
# Magento_ImportExport module
2+
3+
This module provides a framework and basic functionality for importing/exporting various entities in Magento.
24
It can be disabled and in such case all dependent import/export functionality (products, customers, orders etc.) will be disabled in Magento.
5+
6+
## Installation
7+
8+
The Magento_ImportExport module creates the following tables in the database:
9+
- `importexport_importdata`
10+
- `import_history`
11+
12+
All database schema changes made by this module are rolled back when the module gets disabled and setup:upgrade command is run.
13+
14+
For information about a module installation in Magento 2, see [Enable or disable modules](https://devdocs.magento.com/guides/v2.4/install-gde/install/cli/install-cli-subcommands-enable.html).
15+
16+
## Structure
17+
18+
`Files/` - the directory that contains sample import files.
19+
20+
For information about a typical file structure of a module in Magento 2, see [Module file structure](http://devdocs.magento.com/guides/v2.4/extension-dev-guide/build/module-file-structure.html#module-file-structure).
21+
22+
## Extensibility
23+
24+
Extension developers can interact with the Magento_ImportExport module. For more information about the Magento extension mechanism, see [Magento plugins](https://devdocs.magento.com/guides/v2.4/extension-dev-guide/plugins.html).
25+
26+
[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.4/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_ImportExport module.
27+
28+
### Layouts
29+
30+
This module introduces the following layout handles in the `view/frontend/layout` directory:
31+
32+
- `adminhtml_export_getfilter`
33+
- `adminhtml_export_index`
34+
- `adminhtml_history_grid_block`
35+
- `adminhtml_history_index`
36+
- `adminhtml_import_busy`
37+
- `adminhtml_import_index`
38+
- `adminhtml_import_start`
39+
- `adminhtml_import_validate`
40+
41+
For more information about a layout in Magento 2, see the [Layout documentation](http://devdocs.magento.com/guides/v2.4/frontend-dev-guide/layouts/layout-overview.html).
42+
43+
### UI components
44+
45+
You can extend an export updates using the configuration files located in the `view/adminhtml/ui_component` directory:
46+
47+
- `export_grid`
48+
49+
For information about a UI component in Magento 2, see [Overview of UI components](http://devdocs.magento.com/guides/v2.4/ui_comp_guide/bk-ui_comps.html).
50+
51+
### Public APIs
52+
53+
- `Magento\ImportExport\Api\Data\ExportInfoInterface`
54+
- getter and setter interface with data needed for export
55+
56+
- `Magento\ImportExport\Api\Data\ExtendedExportInfoInterface`
57+
- extends `Magento\ImportExport\Api\Data\ExportInfoInterface`. Contains data for skipped attributes
58+
59+
- `\Magento\ImportExport\Api\ExportManagementInterface`
60+
- Executing actual export and returns export data
61+
62+
For information about a public API in Magento 2, see [Public interfaces & APIs](http://devdocs.magento.com/guides/v2.4/extension-dev-guide/api-concepts.html).
63+
64+
## Additional information
65+
66+
#### Message Queue Consumer
67+
68+
- `exportProcessor` - consumer to run export process
69+
70+
[Learn how to manage Message Queues](https://devdocs.magento.com/guides/v2.4/config-guide/mq/manage-message-queues.html).
71+
72+
#### Create custom import entity
73+
74+
1. Declare the new import entity in `etc/import.xml`
75+
2. Create an import model
76+
77+
#### Create custom export entity
78+
79+
1. Declare the new import entity in `etc/export.xml`
80+
2. Create an export model
81+
82+
You can get more information about import/export processes in magento at the articles:
83+
- [Create custom import entity](https://devdocs.magento.com/guides/v2.4/ext-best-practices/tutorials/custom-import-entity.html)
84+
- [Import](https://docs.magento.com/user-guide/system/data-import.html)
85+
- [Export](https://docs.magento.com/user-guide/system/data-export.html)

0 commit comments

Comments
 (0)