Skip to content

Commit a1fa1c6

Browse files
ENGCOM-7873: #1391: SaveAssetsKeywordsInterface to delete obsolete keywords #29207
- Merge Pull Request #29207 from jmonteros422/magento2-1:1391-SaveAssetsKeywordsInterface-to-delete-obsolete-keywords - Merged commits: 1. a3e9fea 2. 7c2511a 3. d81d262 4. fe0be1d 5. 659071c 6. b166cf5 7. cc4c5d0 8. 958fee3
2 parents c6f5b12 + 958fee3 commit a1fa1c6

File tree

4 files changed

+164
-35
lines changed

4 files changed

+164
-35
lines changed

app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/SaveAssetLinks.php

Lines changed: 111 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
use Magento\Framework\App\ResourceConnection;
1111
use Magento\Framework\DB\Adapter\AdapterInterface;
1212
use Magento\Framework\DB\Adapter\Pdo\Mysql;
13+
use Magento\Framework\Exception\CouldNotDeleteException;
1314
use Magento\Framework\Exception\CouldNotSaveException;
1415
use Magento\MediaGalleryApi\Api\Data\KeywordInterface;
16+
use Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface;
1517
use Psr\Log\LoggerInterface;
1618

1719
/**
@@ -28,49 +30,79 @@ class SaveAssetLinks
2830
*/
2931
private $resourceConnection;
3032

33+
/**
34+
* @var GetAssetsKeywordsInterface
35+
*/
36+
private $getAssetsKeywords;
37+
3138
/**
3239
* @var LoggerInterface
3340
*/
3441
private $logger;
3542

3643
/**
44+
* @param GetAssetsKeywordsInterface $getAssetsKeywords
3745
* @param ResourceConnection $resourceConnection
3846
* @param LoggerInterface $logger
3947
*/
4048
public function __construct(
49+
GetAssetsKeywordsInterface $getAssetsKeywords,
4150
ResourceConnection $resourceConnection,
4251
LoggerInterface $logger
4352
) {
53+
$this->getAssetsKeywords = $getAssetsKeywords;
4454
$this->resourceConnection = $resourceConnection;
4555
$this->logger = $logger;
4656
}
4757

4858
/**
49-
* Save asset keywords links
59+
* Process insert and deletion of asset keywords links
5060
*
5161
* @param int $assetId
5262
* @param KeywordInterface[] $keywordIds
5363
*
64+
* @throws CouldNotDeleteException
5465
* @throws CouldNotSaveException
5566
*/
5667
public function execute(int $assetId, array $keywordIds): void
5768
{
69+
$currentKeywordIds = $this->getCurrentKeywordIds($assetId);
70+
71+
$obsoleteKeywordIds = array_diff($currentKeywordIds, $keywordIds);
72+
$newKeywordIds = array_diff($keywordIds, $currentKeywordIds);
73+
74+
$this->deleteAssetKeywords($assetId, $obsoleteKeywordIds);
75+
$this->insertAssetKeywords($assetId, $newKeywordIds);
76+
}
77+
78+
/**
79+
* Save new asset keyword links
80+
*
81+
* @param int $assetId
82+
* @param int[] $keywordIds
83+
*
84+
* @throws CouldNotSaveException
85+
*/
86+
private function insertAssetKeywords(int $assetId, array $keywordIds): void
87+
{
88+
if (empty($keywordIds)) {
89+
return;
90+
}
5891
try {
5992
$values = [];
93+
6094
foreach ($keywordIds as $keywordId) {
6195
$values[] = [$assetId, $keywordId];
6296
}
6397

64-
if (!empty($values)) {
65-
/** @var Mysql $connection */
66-
$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
72-
);
73-
}
98+
/** @var Mysql $connection */
99+
$connection = $this->resourceConnection->getConnection();
100+
$connection->insertArray(
101+
$this->resourceConnection->getTableName(self::TABLE_ASSET_KEYWORD),
102+
[self::FIELD_ASSET_ID, self::FIELD_KEYWORD_ID],
103+
$values,
104+
AdapterInterface::INSERT_IGNORE
105+
);
74106
} catch (\Exception $exception) {
75107
$this->logger->critical($exception);
76108
throw new CouldNotSaveException(
@@ -79,4 +111,72 @@ public function execute(int $assetId, array $keywordIds): void
79111
);
80112
}
81113
}
114+
115+
/**
116+
* Delete obsolete asset keyword links
117+
*
118+
* @param int $assetId
119+
* @param int[] $obsoleteKeywordIds
120+
* @throws CouldNotDeleteException
121+
*/
122+
private function deleteAssetKeywords(int $assetId, array $obsoleteKeywordIds): void
123+
{
124+
if (empty($obsoleteKeywordIds)) {
125+
return;
126+
}
127+
try {
128+
/** @var Mysql $connection */
129+
$connection = $this->resourceConnection->getConnection();
130+
$connection->delete(
131+
$connection->getTableName(
132+
self::TABLE_ASSET_KEYWORD
133+
),
134+
[
135+
self::FIELD_KEYWORD_ID . ' in (?)' => $obsoleteKeywordIds,
136+
self::FIELD_ASSET_ID . ' = ?' => $assetId
137+
]
138+
);
139+
} catch (\Exception $exception) {
140+
$this->logger->critical($exception);
141+
throw new CouldNotDeleteException(
142+
__('Could not delete obsolete asset keyword links'),
143+
$exception
144+
);
145+
}
146+
}
147+
148+
/**
149+
* Get current keyword ids of an asset
150+
*
151+
* @param int $assetId
152+
* @return int[]
153+
*/
154+
private function getCurrentKeywordIds(int $assetId): array
155+
{
156+
$currentKeywordsData = $this->getAssetsKeywords->execute([$assetId]);
157+
158+
if (empty($currentKeywordsData)) {
159+
return [];
160+
}
161+
162+
return $this->getKeywordIdsFromKeywordData(
163+
$currentKeywordsData[$assetId]->getKeywords()
164+
);
165+
}
166+
167+
/**
168+
* Get keyword ids from keyword data
169+
*
170+
* @param KeywordInterface[] $keywordsData
171+
* @return int[]
172+
*/
173+
private function getKeywordIdsFromKeywordData(array $keywordsData): array
174+
{
175+
return array_map(
176+
function (KeywordInterface $keyword): int {
177+
return $keyword->getId();
178+
},
179+
$keywordsData
180+
);
181+
}
82182
}

app/code/Magento/MediaGallery/Model/ResourceModel/Keyword/SaveAssetsKeywords.php

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,19 +93,17 @@ private function saveAssetKeywords(array $keywords, int $assetId): void
9393
$data[] = $keyword->getKeyword();
9494
}
9595

96-
if (empty($data)) {
97-
return;
96+
if (!empty($data)) {
97+
/** @var Mysql $connection */
98+
$connection = $this->resourceConnection->getConnection();
99+
$connection->insertArray(
100+
$this->resourceConnection->getTableName(self::TABLE_KEYWORD),
101+
[self::KEYWORD],
102+
$data,
103+
AdapterInterface::INSERT_IGNORE
104+
);
98105
}
99106

100-
/** @var Mysql $connection */
101-
$connection = $this->resourceConnection->getConnection();
102-
$connection->insertArray(
103-
$this->resourceConnection->getTableName(self::TABLE_KEYWORD),
104-
[self::KEYWORD],
105-
$data,
106-
AdapterInterface::INSERT_IGNORE
107-
);
108-
109107
$this->saveAssetLinks->execute($assetId, $this->getKeywordIds($data));
110108
}
111109

app/code/Magento/MediaGallery/Test/Unit/Model/ResourceModel/Keyword/SaveAssetLinksTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Magento\Framework\DB\Adapter\AdapterInterface;
1212
use Magento\Framework\Exception\CouldNotSaveException;
1313
use Magento\MediaGallery\Model\ResourceModel\Keyword\SaveAssetLinks;
14+
use Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface;
1415
use PHPUnit\Framework\MockObject\MockObject;
1516
use PHPUnit\Framework\TestCase;
1617
use Psr\Log\LoggerInterface;
@@ -32,6 +33,11 @@ class SaveAssetLinksTest extends TestCase
3233
*/
3334
private $resourceConnectionMock;
3435

36+
/**
37+
* @var GetAssetsKeywordsInterface
38+
*/
39+
private $getAssetsKeywords;
40+
3541
/**
3642
* @var LoggerInterface|MockObject
3743
*/
@@ -44,9 +50,11 @@ protected function setUp(): void
4450
{
4551
$this->connectionMock = $this->getMockForAbstractClass(AdapterInterface::class);
4652
$this->resourceConnectionMock = $this->createMock(ResourceConnection::class);
53+
$this->getAssetsKeywords = $this->getMockForAbstractClass(GetAssetsKeywordsInterface::class);
4754
$this->loggerMock = $this->getMockForAbstractClass(LoggerInterface::class);
4855

4956
$this->sut = new SaveAssetLinks(
57+
$this->getAssetsKeywords,
5058
$this->resourceConnectionMock,
5159
$this->loggerMock
5260
);
@@ -60,6 +68,7 @@ protected function setUp(): void
6068
* @param int $assetId
6169
* @param array $keywordIds
6270
* @param array $values
71+
* @throws CouldNotSaveException
6372
*/
6473
public function testAssetKeywordsSave(int $assetId, array $keywordIds, array $values): void
6574
{

dev/tests/integration/testsuite/Magento/MediaGallery/Model/ResourceModel/AssetKeywordsTest.php

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
namespace Magento\MediaGallery\Model\ResourceModel;
99

1010
use Behat\Gherkin\Keywords\KeywordsInterface;
11-
use Magento\MediaGalleryApi\Api\Data\KeywordInterfaceFactory;
12-
use Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterfaceFactory;
1311
use Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterface;
12+
use Magento\MediaGalleryApi\Api\Data\AssetKeywordsInterfaceFactory;
13+
use Magento\MediaGalleryApi\Api\Data\KeywordInterfaceFactory;
1414
use Magento\MediaGalleryApi\Api\GetAssetsByPathsInterface;
1515
use Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface;
1616
use Magento\MediaGalleryApi\Api\SaveAssetsKeywordsInterface;
@@ -66,29 +66,44 @@ protected function setUp(): void
6666
*
6767
* @magentoDataFixture Magento/MediaGallery/_files/media_asset.php
6868
* @dataProvider keywordsProvider
69-
* @param array $keywords
69+
* @param string[] $keywords
70+
* @param string[] $updatedKeywords
7071
* @throws \Magento\Framework\Exception\LocalizedException
7172
*/
72-
public function testSaveAndGetKeywords(array $keywords): void
73+
public function testSaveAndGetKeywords(array $keywords, array $updatedKeywords): void
7374
{
74-
$keywords = ['pear', 'plum'];
75-
7675
$loadedAssets = $this->getAssetsByPath->execute([self::FIXTURE_ASSET_PATH]);
7776
$this->assertCount(1, $loadedAssets);
7877
$loadedAsset = current($loadedAssets);
7978

79+
$this->updateAssetKeywords($loadedAsset->getId(), $keywords);
80+
$this->updateAssetKeywords($loadedAsset->getId(), $updatedKeywords);
81+
}
82+
83+
/**
84+
* Update Asset keywords
85+
*
86+
* @param int $assetId
87+
* @param string[] $keywords
88+
*/
89+
private function updateAssetKeywords(int $assetId, array $keywords): void
90+
{
8091
$assetKeywords = $this->assetsKeywordsFactory->create(
8192
[
82-
'assetId' => $loadedAsset->getId(),
93+
'assetId' => $assetId,
8394
'keywords' => $this->getKeywords($keywords)
8495
]
8596
);
8697

8798
$this->saveAssetsKeywords->execute([$assetKeywords]);
88-
$loadedAssetKeywords = $this->getAssetsKeywords->execute([$loadedAsset->getId()]);
99+
$loadedAssetKeywords = $this->getAssetsKeywords->execute([$assetId]);
89100

90-
$this->assertCount(1, $loadedAssetKeywords);
101+
if (empty($keywords)) {
102+
$this->assertEmpty($loadedAssetKeywords);
103+
return;
104+
}
91105

106+
$this->assertCount(1, $loadedAssetKeywords);
92107
/** @var AssetKeywordsInterface $loadedAssetKeyword */
93108
$loadedAssetKeyword = current($loadedAssetKeywords);
94109

@@ -115,10 +130,17 @@ public function testSaveAndGetKeywords(array $keywords): void
115130
public function keywordsProvider(): array
116131
{
117132
return [
118-
[['one-keyword']],
119-
[['кириллица']],
120-
[['plum', 'pear']],
121-
[[]]
133+
[['one-keyword'],['plum','orange']],
134+
[['кириллица'],[]],
135+
[[],['plum']],
136+
[['plum', 'pear'],['plum','pear']],
137+
[['plum', 'pear'],['plum','orange']],
138+
[['plum', 'pear','grape'],['plum','orange']],
139+
[['plum', 'pear','grape'],['mango']],
140+
[['plum', 'pear','grape'],['orange']],
141+
[['plum', 'pear','grape'],[]],
142+
[['plum', 'pear'],['plum', 'pear','grape','mango','orange']],
143+
[[],[]]
122144
];
123145
}
124146

0 commit comments

Comments
 (0)