Skip to content

Commit c35093a

Browse files
🔃 [Magento Community Engineering] Community Contributions - 2.4-develop
Accepted Community Pull Requests: - #28739: Close prompt immediately after click ok instead of wait ajax request (by @Nazar65) - #28351: Generated code is not consistent with Magento requirements and Coding Standard (by @lbajsarowicz) - #27429: Add ACL role ID to category tree cache id (by @quangdo-aligent) - #27567: #27091 Removed array print while setup upgrade (by @srsathish92) - #28515: Changed array creation to be in line with the class (by @litsher) - #28460: Product CSV import error report file missing (by @engcom-Charlie) - #28421: Error when creating a store view if there are CMS pages with the same URL key (by @engcom-Charlie) - #27965: #27962 Migrate Plugin out of Framework (to Theme module) (by @lbajsarowicz) Fixed GitHub Issues: - #28376: [Issue] Generated code is not consistent with Magento requirements and Coding Standard (reported by @m2-backlog[bot]) has been fixed in #28351 by @lbajsarowicz in 2.4-develop branch Related commits: 1. fcc3e27 2. 3f87a5b - #28306: [Issue] Add ACL role ID to category tree cache id (reported by @m2-backlog[bot]) has been fixed in #27429 by @quangdo-aligent in 2.4-develop branch Related commits: 1. 54a11eb 2. f1c8ad5 3. 207a449 4. 61f847e 5. 5a4e93f 6. e5b64f5 7. 06d3e3a 8. 179a72f 9. a096270 - #27091: Magento 2.3.4 array print while setup upgrade (reported by @RHapani) has been fixed in #27567 by @srsathish92 in 2.4-develop branch Related commits: 1. d95a65a 2. 981df7b 3. 16ebd28 4. a044c53 5. 075f997 6. 479166e - #28795: [Issue] Changed array creation to be in line with the class (reported by @m2-assistant[bot]) has been fixed in #28515 by @litsher in 2.4-develop branch Related commits: 1. 8901baa 2. 4418a95 3. f44321f 4. ba12f12 - #28420: Product CSV import error report file missing (reported by @mischabraam) has been fixed in #28460 by @engcom-Charlie in 2.4-develop branch Related commits: 1. d4d8ef4 2. 597d65f - #28357: Error when creating a store view if there are CMS pages with the same URL key (reported by @stupachenko) has been fixed in #28421 by @engcom-Charlie in 2.4-develop branch Related commits: 1. 035aaf0 2. f1d1450 3. 9d417ec - #27962: Plugins in \Magento\Framework namespace (reported by @lbajsarowicz) has been fixed in #27965 by @lbajsarowicz in 2.4-develop branch Related commits: 1. d938e7b 2. ae58f56 3. 02aae13 4. a84633e 5. 7ff6063
2 parents 3b19d14 + 757c11a commit c35093a

File tree

15 files changed

+211
-70
lines changed

15 files changed

+211
-70
lines changed

app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77

88
namespace Magento\Catalog\Test\Unit\Ui\DataProvider\Product\Form\Modifier;
99

10-
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
11-
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
1210
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Categories;
11+
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
12+
use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
1313
use Magento\Framework\AuthorizationInterface;
1414
use Magento\Framework\DB\Helper as DbHelper;
1515
use Magento\Framework\UrlInterface;
1616
use Magento\Store\Model\Store;
17+
use Magento\Backend\Model\Auth\Session;
18+
use Magento\Authorization\Model\Role;
19+
use Magento\User\Model\User;
1720
use PHPUnit\Framework\MockObject\MockObject;
1821

1922
/**
@@ -51,6 +54,11 @@ class CategoriesTest extends AbstractModifierTest
5154
*/
5255
private $authorizationMock;
5356

57+
/**
58+
* @var Session|MockObject
59+
*/
60+
private $sessionMock;
61+
5462
protected function setUp(): void
5563
{
5664
parent::setUp();
@@ -72,7 +80,10 @@ protected function setUp(): void
7280
$this->authorizationMock = $this->getMockBuilder(AuthorizationInterface::class)
7381
->disableOriginalConstructor()
7482
->getMockForAbstractClass();
75-
83+
$this->sessionMock = $this->getMockBuilder(Session::class)
84+
->setMethods(['getUser'])
85+
->disableOriginalConstructor()
86+
->getMock();
7687
$this->categoryCollectionFactoryMock->expects($this->any())
7788
->method('create')
7889
->willReturn($this->categoryCollectionMock);
@@ -88,6 +99,26 @@ protected function setUp(): void
8899
$this->categoryCollectionMock->expects($this->any())
89100
->method('getIterator')
90101
->willReturn(new \ArrayIterator([]));
102+
103+
$roleAdmin = $this->getMockBuilder(Role::class)
104+
->setMethods(['getId'])
105+
->disableOriginalConstructor()
106+
->getMock();
107+
$roleAdmin->expects($this->any())
108+
->method('getId')
109+
->willReturn(0);
110+
111+
$userAdmin = $this->getMockBuilder(User::class)
112+
->setMethods(['getRole'])
113+
->disableOriginalConstructor()
114+
->getMock();
115+
$userAdmin->expects($this->any())
116+
->method('getRole')
117+
->willReturn($roleAdmin);
118+
119+
$this->sessionMock->expects($this->any())
120+
->method('getUser')
121+
->willReturn($userAdmin);
91122
}
92123

93124
/**
@@ -101,11 +132,28 @@ protected function createModel()
101132
'locator' => $this->locatorMock,
102133
'categoryCollectionFactory' => $this->categoryCollectionFactoryMock,
103134
'arrayManager' => $this->arrayManagerMock,
104-
'authorization' => $this->authorizationMock
135+
'authorization' => $this->authorizationMock,
136+
'session' => $this->sessionMock
105137
]
106138
);
107139
}
108140

141+
/**
142+
* @param object $object
143+
* @param string $method
144+
* @param array $args
145+
* @return mixed
146+
* @throws \ReflectionException
147+
*/
148+
private function invokeMethod($object, $method, $args = [])
149+
{
150+
$class = new \ReflectionClass(Categories::class);
151+
$method = $class->getMethod($method);
152+
$method->setAccessible(true);
153+
154+
return $method->invokeArgs($object, $args);
155+
}
156+
109157
public function testModifyData()
110158
{
111159
$this->assertSame([], $this->getModel()->modifyData([]));
@@ -176,4 +224,44 @@ public function modifyMetaLockedDataProvider()
176224
{
177225
return [[true], [false]];
178226
}
227+
228+
/**
229+
* Asserts that a user with an ACL role ID of 0 and a user with an ACL role ID of 1 do not have the same cache IDs
230+
* Assumes a store ID of 0
231+
*
232+
* @throws \ReflectionException
233+
*/
234+
public function testAclCacheIds()
235+
{
236+
$categoriesAdmin = $this->createModel();
237+
$cacheIdAdmin = $this->invokeMethod($categoriesAdmin, 'getCategoriesTreeCacheId', [0]);
238+
239+
$roleAclUser = $this->getMockBuilder(Role::class)
240+
->disableOriginalConstructor()
241+
->getMock();
242+
$roleAclUser->expects($this->any())
243+
->method('getId')
244+
->willReturn(1);
245+
246+
$userAclUser = $this->getMockBuilder(User::class)
247+
->disableOriginalConstructor()
248+
->getMock();
249+
$userAclUser->expects($this->any())
250+
->method('getRole')
251+
->will($this->returnValue($roleAclUser));
252+
253+
$this->sessionMock = $this->getMockBuilder(Session::class)
254+
->setMethods(['getUser'])
255+
->disableOriginalConstructor()
256+
->getMock();
257+
258+
$this->sessionMock->expects($this->any())
259+
->method('getUser')
260+
->will($this->returnValue($userAclUser));
261+
262+
$categoriesAclUser = $this->createModel();
263+
$cacheIdAclUser = $this->invokeMethod($categoriesAclUser, 'getCategoriesTreeCacheId', [0]);
264+
265+
$this->assertNotEquals($cacheIdAdmin, $cacheIdAclUser);
266+
}
179267
}

app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
use Magento\Framework\UrlInterface;
1919
use Magento\Framework\Stdlib\ArrayManager;
2020
use Magento\Framework\AuthorizationInterface;
21+
use Magento\Backend\Model\Auth\Session;
2122

2223
/**
2324
* Data provider for categories field of product page
2425
*
2526
* @api
2627
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
28+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
2729
* @since 101.0.0
2830
*/
2931
class Categories extends AbstractModifier
@@ -86,6 +88,11 @@ class Categories extends AbstractModifier
8688
*/
8789
private $authorization;
8890

91+
/**
92+
* @var Session
93+
*/
94+
private $session;
95+
8996
/**
9097
* @param LocatorInterface $locator
9198
* @param CategoryCollectionFactory $categoryCollectionFactory
@@ -94,6 +101,7 @@ class Categories extends AbstractModifier
94101
* @param ArrayManager $arrayManager
95102
* @param SerializerInterface $serializer
96103
* @param AuthorizationInterface $authorization
104+
* @param Session $session
97105
*/
98106
public function __construct(
99107
LocatorInterface $locator,
@@ -102,7 +110,8 @@ public function __construct(
102110
UrlInterface $urlBuilder,
103111
ArrayManager $arrayManager,
104112
SerializerInterface $serializer = null,
105-
AuthorizationInterface $authorization = null
113+
AuthorizationInterface $authorization = null,
114+
Session $session = null
106115
) {
107116
$this->locator = $locator;
108117
$this->categoryCollectionFactory = $categoryCollectionFactory;
@@ -111,6 +120,7 @@ public function __construct(
111120
$this->arrayManager = $arrayManager;
112121
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
113122
$this->authorization = $authorization ?: ObjectManager::getInstance()->get(AuthorizationInterface::class);
123+
$this->session = $session ?: ObjectManager::getInstance()->get(Session::class);
114124
}
115125

116126
/**
@@ -370,10 +380,16 @@ protected function getCategoriesTree($filter = null)
370380
* @param string $filter
371381
* @return string
372382
*/
373-
private function getCategoriesTreeCacheId(int $storeId, string $filter = '') : string
383+
private function getCategoriesTreeCacheId(int $storeId, string $filter = ''): string
374384
{
385+
if ($this->session->getUser() !== null) {
386+
return self::CATEGORY_TREE_ID
387+
. '_' . (string)$storeId
388+
. '_' . $this->session->getUser()->getAclRole()
389+
. '_' . $filter;
390+
}
375391
return self::CATEGORY_TREE_ID
376-
. '_' . (string) $storeId
392+
. '_' . (string)$storeId
377393
. '_' . $filter;
378394
}
379395

app/code/Magento/CmsUrlRewrite/Plugin/Cms/Model/Store/View.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\CmsUrlRewrite\Plugin\Cms\Model\Store;
99

10+
use Magento\Cms\Api\Data\PageInterface;
1011
use Magento\Cms\Api\PageRepositoryInterface;
1112
use Magento\CmsUrlRewrite\Model\CmsPageUrlRewriteGenerator;
1213
use Magento\Framework\Api\SearchCriteriaBuilder;
@@ -21,6 +22,8 @@
2122
*/
2223
class View
2324
{
25+
private const ALL_STORE_VIEWS = '0';
26+
2427
/**
2528
* @var UrlPersistInterface
2629
*/
@@ -89,14 +92,27 @@ private function generateCmsPagesUrls(int $storeId): array
8992
{
9093
$rewrites = [];
9194
$urls = [];
92-
$searchCriteria = $this->searchCriteriaBuilder->create();
93-
$cmsPagesCollection = $this->pageRepository->getList($searchCriteria)->getItems();
94-
foreach ($cmsPagesCollection as $page) {
95+
96+
foreach ($this->getCmsPageItems() as $page) {
9597
$page->setStoreId($storeId);
9698
$rewrites[] = $this->cmsPageUrlRewriteGenerator->generate($page);
9799
}
98100
$urls = array_merge($urls, ...$rewrites);
99101

100102
return $urls;
101103
}
104+
105+
/**
106+
* Return cms page items for all store view
107+
*
108+
* @return PageInterface[]
109+
*/
110+
private function getCmsPageItems(): array
111+
{
112+
$searchCriteria = $this->searchCriteriaBuilder->addFilter('store_id', self::ALL_STORE_VIEWS)
113+
->create();
114+
$list = $this->pageRepository->getList($searchCriteria);
115+
116+
return $list->getItems();
117+
}
102118
}

app/code/Magento/Developer/Console/Command/patch_template.php.dist

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace %moduleName%\Setup\Patch\%patchType%;
89

@@ -36,20 +37,18 @@ class %class% implements %implementsInterfaces%
3637
}
3738
%revertFunction%
3839
/**
39-
* {@inheritdoc}
40+
* @inheritdoc
4041
*/
4142
public function getAliases()
4243
{
4344
return [];
4445
}
4546

4647
/**
47-
* {@inheritdoc}
48+
* @inheritdoc
4849
*/
4950
public static function getDependencies()
5051
{
51-
return [
52-
53-
];
52+
return [];
5453
}
5554
}

app/code/Magento/ImportExport/Model/Export/Adapter/Csv.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@ public function destruct()
5454
{
5555
if (is_object($this->_fileHandler)) {
5656
$this->_fileHandler->close();
57+
$this->resolveDestination();
58+
}
59+
}
60+
61+
/**
62+
* Remove temporary destination
63+
*
64+
* @return void
65+
*/
66+
private function resolveDestination(): void
67+
{
68+
// only temporary file located directly in var folder
69+
if (strpos($this->_destination, '/') === false) {
5770
$this->_directoryHandle->delete($this->_destination);
5871
}
5972
}

app/code/Magento/Sales/Model/Order/Pdf/Items/Invoice/DefaultInvoice.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,9 @@ public function draw()
8080
$lines = [];
8181

8282
// draw Product name
83-
$lines[0] = [
84-
[
83+
$lines[0][] = [
8584
'text' => $this->string->split($this->prepareText((string)$item->getName()), 35, true, true),
8685
'feed' => 35
87-
]
8886
];
8987

9088
// draw SKU

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
<preference for="Magento\Framework\App\Router\PathConfigInterface" type="Magento\Store\Model\PathConfig" />
6666
<type name="Magento\Framework\App\ActionInterface">
6767
<plugin name="storeCheck" type="Magento\Store\App\Action\Plugin\StoreCheck"/>
68-
<plugin name="designLoader" type="Magento\Framework\App\Action\Plugin\LoadDesignPlugin"/>
6968
<plugin name="eventDispatch" type="Magento\Framework\App\Action\Plugin\EventDispatchPlugin"/>
7069
<plugin name="actionFlagNoDispatch" type="Magento\Framework\App\Action\Plugin\ActionFlagNoDispatchPlugin"/>
7170
</type>

lib/internal/Magento/Framework/App/Action/Plugin/LoadDesignPlugin.php renamed to app/code/Magento/Theme/Plugin/LoadDesignPlugin.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* See COPYING.txt for license details.
55
*/
66

7-
namespace Magento\Framework\App\Action\Plugin;
7+
namespace Magento\Theme\Plugin;
88

99
use Magento\Framework\App\ActionInterface;
1010
use Magento\Framework\Config\Dom\ValidationException;
@@ -21,12 +21,12 @@ class LoadDesignPlugin
2121
/**
2222
* @var DesignLoader
2323
*/
24-
protected $_designLoader;
24+
private $designLoader;
2525

2626
/**
2727
* @var MessageManagerInterface
2828
*/
29-
protected $messageManager;
29+
private $messageManager;
3030

3131
/**
3232
* @param DesignLoader $designLoader
@@ -36,7 +36,7 @@ public function __construct(
3636
DesignLoader $designLoader,
3737
MessageManagerInterface $messageManager
3838
) {
39-
$this->_designLoader = $designLoader;
39+
$this->designLoader = $designLoader;
4040
$this->messageManager = $messageManager;
4141
}
4242

@@ -50,7 +50,7 @@ public function __construct(
5050
public function beforeExecute(ActionInterface $subject)
5151
{
5252
try {
53-
$this->_designLoader->load();
53+
$this->designLoader->load();
5454
} catch (LocalizedException $e) {
5555
if ($e->getPrevious() instanceof ValidationException) {
5656
/** @var MessageInterface $message */

0 commit comments

Comments
 (0)