5
5
*/
6
6
namespace Magento \Catalog \Model \Product \Gallery ;
7
7
8
+ use Magento \Catalog \Api \Data \ProductInterface ;
9
+ use Magento \Catalog \Api \ProductAttributeRepositoryInterface ;
10
+ use Magento \Catalog \Model \Product ;
11
+ use Magento \Catalog \Model \Product \Media \Config ;
8
12
use Magento \Catalog \Model \ResourceModel \Product \Gallery ;
9
- use Magento \Framework \EntityManager \Operation \ExtensionInterface ;
13
+ use Magento \Eav \Model \ResourceModel \AttributeValue ;
14
+ use Magento \Framework \App \ObjectManager ;
15
+ use Magento \Framework \EntityManager \MetadataPool ;
16
+ use Magento \Framework \Filesystem ;
17
+ use Magento \Framework \Json \Helper \Data ;
18
+ use Magento \MediaStorage \Helper \File \Storage \Database ;
19
+ use Magento \Store \Model \Store ;
20
+ use Magento \Store \Model \StoreManagerInterface ;
10
21
11
22
/**
12
23
* Update handler for catalog product gallery.
13
24
*
14
25
* @api
15
26
* @since 101.0.0
27
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
16
28
*/
17
- class UpdateHandler extends \ Magento \ Catalog \ Model \ Product \ Gallery \ CreateHandler
29
+ class UpdateHandler extends CreateHandler
18
30
{
31
+ /**
32
+ * @var AttributeValue
33
+ */
34
+ private $ attributeValue ;
35
+
36
+ /**
37
+ * @param MetadataPool $metadataPool
38
+ * @param ProductAttributeRepositoryInterface $attributeRepository
39
+ * @param Gallery $resourceModel
40
+ * @param Data $jsonHelper
41
+ * @param Config $mediaConfig
42
+ * @param Filesystem $filesystem
43
+ * @param Database $fileStorageDb
44
+ * @param StoreManagerInterface|null $storeManager
45
+ * @param AttributeValue|null $attributeValue
46
+ */
47
+ public function __construct (
48
+ MetadataPool $ metadataPool ,
49
+ ProductAttributeRepositoryInterface $ attributeRepository ,
50
+ Gallery $ resourceModel ,
51
+ Data $ jsonHelper ,
52
+ Config $ mediaConfig ,
53
+ Filesystem $ filesystem ,
54
+ Database $ fileStorageDb ,
55
+ StoreManagerInterface $ storeManager = null ,
56
+ ?AttributeValue $ attributeValue = null
57
+ ) {
58
+ parent ::__construct (
59
+ $ metadataPool ,
60
+ $ attributeRepository ,
61
+ $ resourceModel ,
62
+ $ jsonHelper ,
63
+ $ mediaConfig ,
64
+ $ filesystem ,
65
+ $ fileStorageDb ,
66
+ $ storeManager
67
+ );
68
+ $ this ->attributeValue = $ attributeValue ?: ObjectManager::getInstance ()->get (AttributeValue::class);
69
+ }
70
+
19
71
/**
20
72
* @inheritdoc
21
73
*
@@ -26,6 +78,7 @@ protected function processDeletedImages($product, array &$images)
26
78
$ filesToDelete = [];
27
79
$ recordsToDelete = [];
28
80
$ picturesInOtherStores = [];
81
+ $ imagesToDelete = [];
29
82
30
83
foreach ($ this ->resourceModel ->getProductImages ($ product , $ this ->extractStoreIds ($ product )) as $ image ) {
31
84
$ picturesInOtherStores [$ image ['filepath ' ]] = true ;
@@ -38,6 +91,7 @@ protected function processDeletedImages($product, array &$images)
38
91
continue ;
39
92
}
40
93
$ recordsToDelete [] = $ image ['value_id ' ];
94
+ $ imagesToDelete [] = $ image ['file ' ];
41
95
$ catalogPath = $ this ->mediaConfig ->getBaseMediaPath ();
42
96
$ isFile = $ this ->mediaDirectory ->isFile ($ catalogPath . $ image ['file ' ]);
43
97
// only delete physical files if they are not used by any other products and if this file exist
@@ -48,8 +102,8 @@ protected function processDeletedImages($product, array &$images)
48
102
}
49
103
}
50
104
105
+ $ this ->deleteMediaAttributeValues ($ product , $ imagesToDelete );
51
106
$ this ->resourceModel ->deleteGallery ($ recordsToDelete );
52
-
53
107
$ this ->removeDeletedImages ($ filesToDelete );
54
108
}
55
109
@@ -94,14 +148,14 @@ protected function processNewImage($product, array &$image)
94
148
/**
95
149
* Retrieve store ids from product.
96
150
*
97
- * @param \Magento\Catalog\Model\ Product $product
151
+ * @param Product $product
98
152
* @return array
99
153
* @since 101.0.0
100
154
*/
101
155
protected function extractStoreIds ($ product )
102
156
{
103
157
$ storeIds = $ product ->getStoreIds ();
104
- $ storeIds [] = \ Magento \ Store \ Model \ Store::DEFAULT_STORE_ID ;
158
+ $ storeIds [] = Store::DEFAULT_STORE_ID ;
105
159
106
160
// Removing current storeId.
107
161
$ storeIds = array_flip ($ storeIds );
@@ -125,5 +179,35 @@ protected function removeDeletedImages(array $files)
125
179
foreach ($ files as $ filePath ) {
126
180
$ this ->mediaDirectory ->delete ($ catalogPath . '/ ' . $ filePath );
127
181
}
182
+ return null ;
183
+ }
184
+
185
+ /**
186
+ * Delete media attributes values for given images
187
+ *
188
+ * @param Product $product
189
+ * @param string[] $images
190
+ */
191
+ private function deleteMediaAttributeValues (Product $ product , array $ images ): void
192
+ {
193
+ if ($ images ) {
194
+ $ values = $ this ->attributeValue ->getValues (
195
+ ProductInterface::class,
196
+ $ product ->getData ($ this ->metadata ->getLinkField ()),
197
+ $ this ->mediaConfig ->getMediaAttributeCodes ()
198
+ );
199
+ $ valuesToDelete = [];
200
+ foreach ($ values as $ value ) {
201
+ if (in_array ($ value ['value ' ], $ images , true )) {
202
+ $ valuesToDelete [] = $ value ;
203
+ }
204
+ }
205
+ if ($ valuesToDelete ) {
206
+ $ this ->attributeValue ->deleteValues (
207
+ ProductInterface::class,
208
+ $ valuesToDelete
209
+ );
210
+ }
211
+ }
128
212
}
129
213
}
0 commit comments