Skip to content

Commit 22643ae

Browse files
Merge branch '2.4-develop' into 2.4-develop
2 parents 5188dcf + 4559910 commit 22643ae

File tree

271 files changed

+13160
-1005
lines changed

Some content is hidden

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

271 files changed

+13160
-1005
lines changed

app/code/Magento/Authorization/Model/Role.php

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,32 @@
55
*/
66
namespace Magento\Authorization\Model;
77

8+
use Magento\Authorization\Model\ResourceModel\Role\Collection;
9+
use Magento\Framework\App\ObjectManager;
10+
use Magento\Framework\Model\AbstractModel;
11+
812
/**
913
* Admin Role Model
1014
*
1115
* @api
1216
* @method int getParentId()
13-
* @method \Magento\Authorization\Model\Role setParentId(int $value)
17+
* @method Role setParentId(int $value)
1418
* @method int getTreeLevel()
15-
* @method \Magento\Authorization\Model\Role setTreeLevel(int $value)
19+
* @method Role setTreeLevel(int $value)
1620
* @method int getSortOrder()
17-
* @method \Magento\Authorization\Model\Role setSortOrder(int $value)
21+
* @method Role setSortOrder(int $value)
1822
* @method string getRoleType()
19-
* @method \Magento\Authorization\Model\Role setRoleType(string $value)
23+
* @method Role setRoleType(string $value)
2024
* @method int getUserId()
21-
* @method \Magento\Authorization\Model\Role setUserId(int $value)
25+
* @method Role setUserId(int $value)
2226
* @method string getUserType()
23-
* @method \Magento\Authorization\Model\Role setUserType(string $value)
27+
* @method Role setUserType(string $value)
2428
* @method string getRoleName()
25-
* @method \Magento\Authorization\Model\Role setRoleName(string $value)
29+
* @method Role setRoleName(string $value)
2630
* @api
2731
* @since 100.0.2
2832
*/
29-
class Role extends \Magento\Framework\Model\AbstractModel
33+
class Role extends AbstractModel
3034
{
3135
/**
3236
* @var string
@@ -38,23 +42,6 @@ class Role extends \Magento\Framework\Model\AbstractModel
3842
*/
3943
protected $_cacheTag = 'user_assigned_role';
4044

41-
/**
42-
* @param \Magento\Framework\Model\Context $context
43-
* @param \Magento\Framework\Registry $registry
44-
* @param \Magento\Authorization\Model\ResourceModel\Role $resource
45-
* @param \Magento\Authorization\Model\ResourceModel\Role\Collection $resourceCollection
46-
* @param array $data
47-
*/
48-
public function __construct( //phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod
49-
\Magento\Framework\Model\Context $context,
50-
\Magento\Framework\Registry $registry,
51-
\Magento\Authorization\Model\ResourceModel\Role $resource,
52-
\Magento\Authorization\Model\ResourceModel\Role\Collection $resourceCollection,
53-
array $data = []
54-
) {
55-
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
56-
}
57-
5845
/**
5946
* @inheritDoc
6047
*/
@@ -70,31 +57,30 @@ public function __sleep()
7057
public function __wakeup()
7158
{
7259
parent::__wakeup();
73-
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
74-
$this->_resource = $objectManager->get(\Magento\Authorization\Model\ResourceModel\Role::class);
75-
$this->_resourceCollection = $objectManager->get(
76-
\Magento\Authorization\Model\ResourceModel\Role\Collection::class
77-
);
60+
$objectManager = ObjectManager::getInstance();
61+
$this->_resource = $objectManager->get(ResourceModel\Role::class);
62+
$this->_resourceCollection = $objectManager->get(Collection::class);
7863
}
7964

8065
/**
81-
* Class constructor
82-
*
83-
* @return void
66+
* @inheritdoc
8467
*/
8568
protected function _construct()
8669
{
87-
$this->_init(\Magento\Authorization\Model\ResourceModel\Role::class);
70+
$this->_init(ResourceModel\Role::class);
8871
}
8972

9073
/**
91-
* Update object into database
74+
* Obsolete method of update
9275
*
9376
* @return $this
77+
* @deprecated Method was never implemented and used.
9478
*/
9579
public function update()
9680
{
97-
$this->getResource()->update($this);
81+
// phpcs:disable Magento2.Functions.DiscouragedFunction
82+
trigger_error('Method was never implemented and used.', E_USER_DEPRECATED);
83+
9884
return $this;
9985
}
10086

app/code/Magento/AwsS3/Test/Mftf/Helper/S3FileAssertions.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,21 @@ public function assertFileExists($filePath, $message = ''): void
149149
$this->assertTrue($this->driver->isExists($filePath), $message);
150150
}
151151

152+
/**
153+
* Asserts that a file with the given glob pattern exists in the given path on the remote storage system
154+
*
155+
* @param string $path
156+
* @param string $pattern
157+
* @param string $message
158+
*
159+
* @throws \Magento\Framework\Exception\FileSystemException
160+
*/
161+
public function assertGlobbedFileExists($path, $pattern, $message = ""): void
162+
{
163+
$files = $this->driver->search($pattern, $path);
164+
$this->assertNotEmpty($files, $message);
165+
}
166+
152167
/**
153168
* Assert a file does not exist on the remote storage system
154169
*
@@ -206,6 +221,24 @@ public function assertFileContainsString($filePath, $text, $message = ""): void
206221
$this->assertStringContainsString($text, $this->driver->fileGetContents($filePath), $message);
207222
}
208223

224+
/**
225+
* Asserts that a file with the given glob pattern at the given path on the remote storage system contains a given string
226+
*
227+
* @param string $path
228+
* @param string $pattern
229+
* @param string $text
230+
* @param int $fileIndex
231+
* @param string $message
232+
* @return void
233+
*
234+
* @throws \Magento\Framework\Exception\FileSystemException
235+
*/
236+
public function assertGlobbedFileContainsString($path, $pattern, $text, $fileIndex = 0, $message = ""): void
237+
{
238+
$files = $this->driver->search($pattern, $path);
239+
$this->assertStringContainsString($text, $this->driver->fileGetContents($files[$fileIndex] ?? ''), $message);
240+
}
241+
209242
/**
210243
* Assert a file on the remote storage system does not contain a given string
211244
*

app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCustomerSearchBundleProductsByKeywordsTest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
</createData>
4242

4343
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex">
44-
<argument name="indices" value="cataloginventory_stock catalog_product_price"/>
44+
<argument name="indices" value=""/>
4545
</actionGroup>
4646
</before>
4747
<after>

app/code/Magento/Catalog/Block/Product/ListProduct.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ private function initializeProductCollection()
461461
// if the product is associated with any category
462462
if ($categories->count()) {
463463
// show products from this category
464-
$this->setCategoryId(current($categories->getIterator())->getId());
464+
$this->setCategoryId($categories->getIterator()->current()->getId());
465465
}
466466
}
467467

app/code/Magento/Catalog/Block/Ui/ProductViewCounter.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ public function getCurrentProductData()
153153
$this->productRenderCollectorComposite
154154
->collect($product, $productRender);
155155
$data = $this->hydrator->extract($productRender);
156+
$data['is_available'] = $product->isAvailable();
156157

157158
$currentProductData = [
158159
'items' => [

app/code/Magento/Catalog/Controller/Adminhtml/Product/MassDelete.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@
99
namespace Magento\Catalog\Controller\Adminhtml\Product;
1010

1111
use Magento\Backend\App\Action\Context;
12+
use Magento\Backend\Model\View\Result\Redirect;
1213
use Magento\Catalog\Api\ProductRepositoryInterface;
14+
use Magento\Catalog\Controller\Adminhtml\Product;
1315
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
1416
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
17+
use Magento\Framework\App\ObjectManager;
1518
use Magento\Framework\Controller\ResultFactory;
1619
use Magento\Framework\Exception\LocalizedException;
1720
use Magento\Ui\Component\MassAction\Filter;
@@ -20,7 +23,7 @@
2023
/**
2124
* Class \Magento\Catalog\Controller\Adminhtml\Product\MassDelete
2225
*/
23-
class MassDelete extends \Magento\Catalog\Controller\Adminhtml\Product implements HttpPostActionInterface
26+
class MassDelete extends Product implements HttpPostActionInterface
2427
{
2528
/**
2629
* Massactions filter
@@ -49,8 +52,8 @@ class MassDelete extends \Magento\Catalog\Controller\Adminhtml\Product implement
4952
* @param Builder $productBuilder
5053
* @param Filter $filter
5154
* @param CollectionFactory $collectionFactory
52-
* @param ProductRepositoryInterface $productRepository
53-
* @param LoggerInterface $logger
55+
* @param ProductRepositoryInterface|null $productRepository
56+
* @param LoggerInterface|null $logger
5457
*/
5558
public function __construct(
5659
Context $context,
@@ -63,20 +66,23 @@ public function __construct(
6366
$this->filter = $filter;
6467
$this->collectionFactory = $collectionFactory;
6568
$this->productRepository = $productRepository ?:
66-
\Magento\Framework\App\ObjectManager::getInstance()->create(ProductRepositoryInterface::class);
69+
ObjectManager::getInstance()->create(ProductRepositoryInterface::class);
6770
$this->logger = $logger ?:
68-
\Magento\Framework\App\ObjectManager::getInstance()->create(LoggerInterface::class);
71+
ObjectManager::getInstance()->create(LoggerInterface::class);
6972
parent::__construct($context, $productBuilder);
7073
}
7174

7275
/**
7376
* Mass Delete Action
7477
*
75-
* @return \Magento\Backend\Model\View\Result\Redirect
78+
* @return Redirect
79+
* @throws LocalizedException
7680
*/
7781
public function execute()
7882
{
7983
$collection = $this->filter->getCollection($this->collectionFactory->create());
84+
$collection->addMediaGalleryData();
85+
8086
$productDeleted = 0;
8187
$productDeletedError = 0;
8288
/** @var \Magento\Catalog\Model\Product $product */
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
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\Catalog\Model\ResourceModel;
9+
10+
use Exception;
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Catalog\Model\Product\Gallery\Processor;
13+
use Magento\Catalog\Model\Product\Media\ConfigInterface as MediaConfig;
14+
use Magento\Catalog\Model\ResourceModel\Product\Gallery;
15+
use Magento\Framework\App\Filesystem\DirectoryList;
16+
use Magento\Framework\DataObject;
17+
use Magento\Framework\Exception\FileSystemException;
18+
use Magento\Framework\Filesystem;
19+
use Psr\Log\LoggerInterface;
20+
21+
/**
22+
* Process media gallery and delete media image after product delete
23+
*/
24+
class MediaImageDeleteProcessor
25+
{
26+
/**
27+
* @var MediaConfig
28+
*/
29+
private $imageConfig;
30+
31+
/**
32+
* @var Filesystem
33+
*/
34+
private $mediaDirectory;
35+
36+
/**
37+
* @var Processor
38+
*/
39+
private $imageProcessor;
40+
41+
/**
42+
* @var Gallery
43+
*/
44+
private $productGallery;
45+
46+
/**
47+
* @var LoggerInterface
48+
*/
49+
private $logger;
50+
51+
/**
52+
* Product constructor.
53+
*
54+
* @param MediaConfig $imageConfig
55+
* @param Filesystem $filesystem
56+
* @param Processor $imageProcessor
57+
* @param Gallery $productGallery
58+
* @param LoggerInterface $logger
59+
* @throws FileSystemException
60+
*/
61+
public function __construct(
62+
MediaConfig $imageConfig,
63+
Filesystem $filesystem,
64+
Processor $imageProcessor,
65+
Gallery $productGallery,
66+
LoggerInterface $logger
67+
) {
68+
$this->imageConfig = $imageConfig;
69+
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
70+
$this->imageProcessor = $imageProcessor;
71+
$this->productGallery = $productGallery;
72+
$this->logger = $logger;
73+
}
74+
75+
/**
76+
* Process $product data and remove image from gallery after product delete
77+
*
78+
* @param DataObject $product
79+
* @return void
80+
*/
81+
public function execute(DataObject $product): void
82+
{
83+
try {
84+
$productImages = $product->getMediaGalleryImages();
85+
foreach ($productImages as $image) {
86+
$imageFile = $image->getFile();
87+
if ($imageFile) {
88+
$this->deleteProductImage($image, $product, $imageFile);
89+
}
90+
}
91+
} catch (Exception $e) {
92+
$this->logger->critical($e);
93+
}
94+
}
95+
96+
/**
97+
* Check if image exists and is not used by any other products
98+
*
99+
* @param string $file
100+
* @return bool
101+
*/
102+
private function canDeleteImage(string $file): bool
103+
{
104+
return $this->productGallery->countImageUses($file) <= 1;
105+
}
106+
107+
/**
108+
* Delete the physical image if it's existed and not used by other products
109+
*
110+
* @param string $imageFile
111+
* @param string $filePath
112+
* @throws FileSystemException
113+
*/
114+
private function deletePhysicalImage(string $imageFile, string $filePath): void
115+
{
116+
if ($this->canDeleteImage($imageFile)) {
117+
$this->mediaDirectory->delete($filePath);
118+
}
119+
}
120+
121+
/**
122+
* Remove product image
123+
*
124+
* @param DataObject $image
125+
* @param ProductInterface $product
126+
* @param string $imageFile
127+
*/
128+
private function deleteProductImage(
129+
DataObject $image,
130+
ProductInterface $product,
131+
string $imageFile
132+
): void {
133+
$catalogPath = $this->imageConfig->getBaseMediaPath();
134+
$filePath = $catalogPath . $imageFile;
135+
136+
if ($this->mediaDirectory->isFile($filePath)) {
137+
try {
138+
$this->productGallery->deleteGallery($image->getValueId());
139+
$this->imageProcessor->removeImage($product, $imageFile);
140+
$this->deletePhysicalImage($imageFile, $filePath);
141+
} catch (Exception $e) {
142+
$this->logger->critical($e);
143+
}
144+
}
145+
}
146+
}

0 commit comments

Comments
 (0)