Skip to content

Commit 73faf9c

Browse files
ENGCOM-8814: catalog_product_entity_media_gallery not cleared when related products deleted. #32273
2 parents 514c7b9 + e319e83 commit 73faf9c

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Catalog\Plugin;
10+
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Catalog\Api\ProductRepositoryInterface;
13+
use Magento\Catalog\Model\Product\Gallery\ReadHandler;
14+
use Magento\Catalog\Model\ResourceModel\Product\Gallery;
15+
16+
/**
17+
* Responsible for deleting images from media gallery after deleting product
18+
*/
19+
class RemoveImagesFromGalleryAfterRemovingProduct
20+
{
21+
/**
22+
* @var Gallery
23+
*/
24+
private $galleryResource;
25+
26+
/**
27+
* @var ReadHandler
28+
*/
29+
private $mediaGalleryReadHandler;
30+
31+
/**
32+
* @param Gallery $galleryResource
33+
* @param ReadHandler $mediaGalleryReadHandler
34+
*/
35+
public function __construct(Gallery $galleryResource, ReadHandler $mediaGalleryReadHandler)
36+
{
37+
$this->galleryResource = $galleryResource;
38+
$this->mediaGalleryReadHandler = $mediaGalleryReadHandler;
39+
}
40+
41+
/**
42+
* Delete media gallery after deleting product
43+
*
44+
* @param ProductRepositoryInterface $subject
45+
* @param callable $proceed
46+
* @param ProductInterface $product
47+
* @return bool
48+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
49+
*/
50+
public function aroundDelete(
51+
ProductRepositoryInterface $subject,
52+
callable $proceed,
53+
ProductInterface $product
54+
): bool {
55+
$mediaGalleryAttributeId = $this->mediaGalleryReadHandler->getAttribute()->getAttributeId();
56+
$mediaGallery = $this->galleryResource->loadProductGalleryByAttributeId($product, $mediaGalleryAttributeId);
57+
58+
$result = $proceed($product);
59+
60+
if ($mediaGallery) {
61+
$this->galleryResource->deleteGallery(array_column($mediaGallery, 'value_id'));
62+
}
63+
64+
return $result;
65+
}
66+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,4 +1319,8 @@
13191319
</argument>
13201320
</arguments>
13211321
</type>
1322+
<type name="Magento\Catalog\Api\ProductRepositoryInterface">
1323+
<plugin name="remove_images_from_gallery_after_removing_product"
1324+
type="Magento\Catalog\Plugin\RemoveImagesFromGalleryAfterRemovingProduct"/>
1325+
</type>
13221326
</config>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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\Product;
9+
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Catalog\Model\Product\Gallery\ReadHandler;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
use PHPUnit\Framework\TestCase;
14+
use Magento\Framework\App\ResourceConnection;
15+
16+
/**
17+
* Test for \Magento\Catalog\Model\ResourceModel\Product\Gallery.
18+
*
19+
* @magentoAppArea adminhtml
20+
*/
21+
class GalleryTest extends TestCase
22+
{
23+
/**
24+
* @var Gallery
25+
*/
26+
private $galleryResource;
27+
28+
/**
29+
* @var ProductRepositoryInterface
30+
*/
31+
private $productRepository;
32+
33+
/**
34+
* @var ResourceConnection
35+
*/
36+
private $resource;
37+
38+
/**
39+
* @var ReadHandler
40+
*/
41+
private $readHandler;
42+
43+
/**
44+
* @inheritDoc
45+
*/
46+
protected function setUp(): void
47+
{
48+
$objectManager = Bootstrap::getObjectManager();
49+
50+
$this->productRepository = $objectManager->create(ProductRepositoryInterface::class);
51+
$this->galleryResource = $objectManager->create(Gallery::class);
52+
$this->resource = $objectManager->create(ResourceConnection::class);
53+
$this->readHandler = $objectManager->create(ReadHandler::class);
54+
}
55+
56+
/**
57+
* Verify catalog_product_entity_media_gallery table will not have data after deleting the product
58+
*
59+
* @magentoDataFixture Magento/Catalog/_files/product_with_image.php
60+
* @magentoDbIsolation disabled
61+
*
62+
* @return void
63+
*/
64+
public function testDeleteProductWithImage(): void
65+
{
66+
$product = $this->productRepository->get('simple');
67+
68+
$attributeId = $this->readHandler->getAttribute()->getAttributeId();
69+
$mediaGalleryData = $this->galleryResource->loadProductGalleryByAttributeId($product, $attributeId);
70+
$values = array_column($mediaGalleryData, 'value_id');
71+
$this->assertNotEmpty($this->getMediaGalleryDataByValues($values));
72+
73+
$this->productRepository->delete($product);
74+
75+
$this->assertEmpty($this->getMediaGalleryDataByValues($values));
76+
}
77+
78+
/**
79+
* Return data from catalog_product_entity_media_gallery_values table
80+
*
81+
* @param array $values
82+
* @return array
83+
*/
84+
private function getMediaGalleryDataByValues(array $values): array
85+
{
86+
$connection = $this->resource->getConnection();
87+
$select = $connection->select()
88+
->from($this->resource->getTableName(Gallery::GALLERY_TABLE))
89+
->where('value_id IN (?)', $values);
90+
91+
return $connection->fetchAll($select);
92+
}
93+
}

0 commit comments

Comments
 (0)