10
10
use Magento \Framework \App \ResourceConnection ;
11
11
use Magento \Framework \DB \Adapter \AdapterInterface ;
12
12
use Magento \Framework \DB \Adapter \Pdo \Mysql ;
13
+ use Magento \Framework \Exception \CouldNotDeleteException ;
13
14
use Magento \Framework \Exception \CouldNotSaveException ;
14
15
use Magento \MediaGalleryApi \Api \Data \KeywordInterface ;
16
+ use Magento \MediaGalleryApi \Api \GetAssetsKeywordsInterface ;
15
17
use Psr \Log \LoggerInterface ;
16
18
17
19
/**
@@ -28,25 +30,33 @@ class SaveAssetLinks
28
30
*/
29
31
private $ resourceConnection ;
30
32
33
+ /**
34
+ * @var GetAssetsKeywordsInterface
35
+ */
36
+ private $ getAssetsKeywordsInterface ;
37
+
31
38
/**
32
39
* @var LoggerInterface
33
40
*/
34
41
private $ logger ;
35
42
36
43
/**
44
+ * @param GetAssetsKeywordsInterface $getAssetsKeywordsInterface
37
45
* @param ResourceConnection $resourceConnection
38
46
* @param LoggerInterface $logger
39
47
*/
40
48
public function __construct (
49
+ GetAssetsKeywordsInterface $ getAssetsKeywordsInterface ,
41
50
ResourceConnection $ resourceConnection ,
42
51
LoggerInterface $ logger
43
52
) {
53
+ $ this ->getAssetsKeywordsInterface = $ getAssetsKeywordsInterface ;
44
54
$ this ->resourceConnection = $ resourceConnection ;
45
55
$ this ->logger = $ logger ;
46
56
}
47
57
48
58
/**
49
- * Save asset keywords links
59
+ * Process insert and deletion of asset keywords links
50
60
*
51
61
* @param int $assetId
52
62
* @param KeywordInterface[] $keywordIds
@@ -56,27 +66,123 @@ public function __construct(
56
66
public function execute (int $ assetId , array $ keywordIds ): void
57
67
{
58
68
try {
59
- $ values = [];
60
- foreach ($ keywordIds as $ keywordId ) {
61
- $ values [] = [$ assetId , $ keywordId ];
69
+ $ this ->deleteAssetKeywords ($ assetId , $ keywordIds );
70
+ $ this ->insertAssetKeywords ($ assetId , $ keywordIds );
71
+ } catch (\Exception $ exception ) {
72
+ $ this ->logger ->critical ($ exception );
73
+ throw new CouldNotSaveException (
74
+ __ ('Could not process asset keyword links ' ),
75
+ $ exception
76
+ );
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Save new asset keyword links
82
+ *
83
+ * @param int $assetId
84
+ * @param array $keywordIds
85
+ * @throws CouldNotSaveException
86
+ */
87
+ private function insertAssetKeywords (int $ assetId , array $ keywordIds ): void
88
+ {
89
+ try {
90
+ if (!empty ($ keywordIds )) {
91
+ $ values = [];
92
+ $ keywordsToInsert = array_diff ($ keywordIds , $ this ->getCurrentKeywords ($ assetId ));
93
+
94
+ foreach ($ keywordsToInsert as $ keywordId ) {
95
+ $ values [] = [$ assetId , $ keywordId ];
96
+ }
97
+
98
+ if (!empty ($ values )) {
99
+ /** @var Mysql $connection */
100
+ $ connection = $ this ->resourceConnection ->getConnection ();
101
+ $ connection ->insertArray (
102
+ $ this ->resourceConnection ->getTableName (self ::TABLE_ASSET_KEYWORD ),
103
+ [self ::FIELD_ASSET_ID , self ::FIELD_KEYWORD_ID ],
104
+ $ values ,
105
+ AdapterInterface::INSERT_IGNORE
106
+ );
107
+ }
62
108
}
109
+ } catch (\Exception $ exception ) {
110
+ $ this ->logger ->critical ($ exception );
111
+ throw new CouldNotSaveException (
112
+ __ ('Could not save asset keyword links ' ),
113
+ $ exception
114
+ );
115
+ }
116
+ }
63
117
64
- if (!empty ($ values )) {
118
+ /**
119
+ * Delete obsolete asset keyword links
120
+ *
121
+ * @param int $assetId
122
+ * @param array $keywords
123
+ * @throws CouldNotDeleteException
124
+ */
125
+ private function deleteAssetKeywords (int $ assetId , array $ keywords ): void
126
+ {
127
+ try {
128
+ $ obsoleteKeywordIds = array_diff ($ this ->getCurrentKeywords ($ assetId ), $ keywords );
129
+
130
+ if (!empty ($ obsoleteKeywordIds )) {
65
131
/** @var Mysql $connection */
66
132
$ connection = $ this ->resourceConnection ->getConnection ();
67
- $ connection ->insertArray (
68
- $ this ->resourceConnection ->getTableName (self ::TABLE_ASSET_KEYWORD ),
69
- [self ::FIELD_ASSET_ID , self ::FIELD_KEYWORD_ID ],
70
- $ values ,
71
- AdapterInterface::INSERT_IGNORE
133
+ $ connection ->delete (
134
+ $ connection ->getTableName (
135
+ self ::TABLE_ASSET_KEYWORD
136
+ ),
137
+ [
138
+ self ::FIELD_KEYWORD_ID . ' in (?) ' => $ obsoleteKeywordIds ,
139
+ self ::FIELD_ASSET_ID . ' = ? ' => $ assetId
140
+ ]
72
141
);
73
142
}
74
143
} catch (\Exception $ exception ) {
75
144
$ this ->logger ->critical ($ exception );
76
- throw new CouldNotSaveException (
77
- __ ('Could not save asset keyword links ' ),
145
+ throw new CouldNotDeleteException (
146
+ __ ('Could not delete obsolete asset keyword links ' ),
78
147
$ exception
79
148
);
80
149
}
81
150
}
151
+
152
+ /**
153
+ * Get current keyword data of an asset
154
+ *
155
+ * @param int $assetId
156
+ * @return array
157
+ */
158
+ private function getCurrentKeywords (int $ assetId ): array
159
+ {
160
+ $ currentKeywordsData = $ this ->getAssetsKeywordsInterface ->execute ([$ assetId ]);
161
+
162
+ if (!empty ($ currentKeywordsData )) {
163
+ $ currentKeywords = $ this ->getKeywordIdsFromKeywordData (
164
+ $ currentKeywordsData [$ assetId ]->getKeywords ()
165
+ );
166
+
167
+ return $ currentKeywords ;
168
+ }
169
+
170
+ return [];
171
+ }
172
+
173
+ /**
174
+ * Get keyword ids from keyword data
175
+ *
176
+ * @param array $keywordsData
177
+ * @return array
178
+ */
179
+ private function getKeywordIdsFromKeywordData (array $ keywordsData ): array
180
+ {
181
+ return array_map (
182
+ function (KeywordInterface $ keyword ): int {
183
+ return $ keyword ->getId ();
184
+ },
185
+ $ keywordsData
186
+ );
187
+ }
82
188
}
0 commit comments