Skip to content

Commit

Permalink
magento/adobe-stock-integration#1391: SaveAssetsKeywordsInterface to …
Browse files Browse the repository at this point in the history
…delete obsolete keywords - Move and improve logic for saving and deleting obsolete asset keyword links
  • Loading branch information
jmonteros422 committed Jul 20, 2020
1 parent 7c2511a commit d81d262
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Adapter\Pdo\Mysql;
use Magento\Framework\Exception\CouldNotDeleteException;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\MediaGalleryApi\Api\Data\KeywordInterface;
use Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface;
use Psr\Log\LoggerInterface;

/**
Expand All @@ -28,25 +30,33 @@ class SaveAssetLinks
*/
private $resourceConnection;

/**
* @var GetAssetsKeywordsInterface
*/
private $getAssetsKeywordsInterface;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @param GetAssetsKeywordsInterface $getAssetsKeywordsInterface
* @param ResourceConnection $resourceConnection
* @param LoggerInterface $logger
*/
public function __construct(
GetAssetsKeywordsInterface $getAssetsKeywordsInterface,
ResourceConnection $resourceConnection,
LoggerInterface $logger
) {
$this->getAssetsKeywordsInterface = $getAssetsKeywordsInterface;
$this->resourceConnection = $resourceConnection;
$this->logger = $logger;
}

/**
* Save asset keywords links
* Process insert and deletion of asset keywords links
*
* @param int $assetId
* @param KeywordInterface[] $keywordIds
Expand All @@ -56,27 +66,123 @@ public function __construct(
public function execute(int $assetId, array $keywordIds): void
{
try {
$values = [];
foreach ($keywordIds as $keywordId) {
$values[] = [$assetId, $keywordId];
$this->deleteAssetKeywords($assetId, $keywordIds);
$this->insertAssetKeywords($assetId, $keywordIds);
} catch (\Exception $exception) {
$this->logger->critical($exception);
throw new CouldNotSaveException(
__('Could not process asset keyword links'),
$exception
);
}
}

/**
* Save new asset keyword links
*
* @param int $assetId
* @param array $keywordIds
* @throws CouldNotSaveException
*/
private function insertAssetKeywords(int $assetId, array $keywordIds): void
{
try {
if (!empty($keywordIds)) {
$values = [];
$keywordsToInsert = array_diff($keywordIds, $this->getCurrentKeywords($assetId));

foreach ($keywordsToInsert as $keywordId) {
$values[] = [$assetId, $keywordId];
}

if (!empty($values)) {
/** @var Mysql $connection */
$connection = $this->resourceConnection->getConnection();
$connection->insertArray(
$this->resourceConnection->getTableName(self::TABLE_ASSET_KEYWORD),
[self::FIELD_ASSET_ID, self::FIELD_KEYWORD_ID],
$values,
AdapterInterface::INSERT_IGNORE
);
}
}
} catch (\Exception $exception) {
$this->logger->critical($exception);
throw new CouldNotSaveException(
__('Could not save asset keyword links'),
$exception
);
}
}

if (!empty($values)) {
/**
* Delete obsolete asset keyword links
*
* @param int $assetId
* @param array $keywords
* @throws CouldNotDeleteException
*/
private function deleteAssetKeywords(int $assetId, array $keywords): void
{
try {
$obsoleteKeywordIds = array_diff($this->getCurrentKeywords($assetId), $keywords);

if (!empty($obsoleteKeywordIds)) {
/** @var Mysql $connection */
$connection = $this->resourceConnection->getConnection();
$connection->insertArray(
$this->resourceConnection->getTableName(self::TABLE_ASSET_KEYWORD),
[self::FIELD_ASSET_ID, self::FIELD_KEYWORD_ID],
$values,
AdapterInterface::INSERT_IGNORE
$connection->delete(
$connection->getTableName(
self::TABLE_ASSET_KEYWORD
),
[
self::FIELD_KEYWORD_ID . ' in (?)' => $obsoleteKeywordIds,
self::FIELD_ASSET_ID . ' = ?' => $assetId
]
);
}
} catch (\Exception $exception) {
$this->logger->critical($exception);
throw new CouldNotSaveException(
__('Could not save asset keyword links'),
throw new CouldNotDeleteException(
__('Could not delete obsolete asset keyword links'),
$exception
);
}
}

/**
* Get current keyword data of an asset
*
* @param int $assetId
* @return array
*/
private function getCurrentKeywords(int $assetId): array
{
$currentKeywordsData = $this->getAssetsKeywordsInterface->execute([$assetId]);

if (!empty($currentKeywordsData)) {
$currentKeywords = $this->getKeywordIdsFromKeywordData(
$currentKeywordsData[$assetId]->getKeywords()
);

return $currentKeywords;
}

return [];
}

/**
* Get keyword ids from keyword data
*
* @param array $keywordsData
* @return array
*/
private function getKeywordIdsFromKeywordData(array $keywordsData): array
{
return array_map(
function (KeywordInterface $keyword): int {
return $keyword->getId();
},
$keywordsData
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Adapter\Pdo\Mysql;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\CouldNotDeleteException;
use Magento\MediaGalleryApi\Api\Data\KeywordInterface;
use Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface;
use Magento\MediaGalleryApi\Api\SaveAssetsKeywordsInterface;
use Psr\Log\LoggerInterface;

Expand All @@ -23,7 +21,6 @@
class SaveAssetsKeywords implements SaveAssetsKeywordsInterface
{
private const TABLE_KEYWORD = 'media_gallery_keyword';
private const TABLE_ASSET_KEYWORD = 'media_gallery_asset_keyword';
private const ID = 'id';
private const KEYWORD = 'keyword';

Expand All @@ -37,11 +34,6 @@ class SaveAssetsKeywords implements SaveAssetsKeywordsInterface
*/
private $saveAssetLinks;

/**
* @var GetAssetsKeywordsInterface
*/
private $getAssetsKeywordsInterface;

/**
* @var LoggerInterface
*/
Expand All @@ -52,18 +44,15 @@ class SaveAssetsKeywords implements SaveAssetsKeywordsInterface
*
* @param ResourceConnection $resourceConnection
* @param SaveAssetLinks $saveAssetLinks
* @param GetAssetsKeywordsInterface $getAssetsKeywordsInterface
* @param LoggerInterface $logger
*/
public function __construct(
ResourceConnection $resourceConnection,
SaveAssetLinks $saveAssetLinks,
GetAssetsKeywordsInterface $getAssetsKeywordsInterface,
LoggerInterface $logger
) {
$this->resourceConnection = $resourceConnection;
$this->saveAssetLinks = $saveAssetLinks;
$this->getAssetsKeywordsInterface = $getAssetsKeywordsInterface;
$this->logger = $logger;
}

Expand Down Expand Up @@ -94,7 +83,6 @@ public function execute(array $assetKeywords): void
*
* @param KeywordInterface[] $keywords
* @param int $assetId
* @throws CouldNotDeleteException
* @throws CouldNotSaveException
* @throws \Zend_Db_Exception
*/
Expand All @@ -109,8 +97,6 @@ private function saveAssetKeywords(array $keywords, int $assetId): void
return;
}

$this->deleteObsoleteAssetKeywords($data, $assetId);

/** @var Mysql $connection */
$connection = $this->resourceConnection->getConnection();
$connection->insertArray(
Expand Down Expand Up @@ -139,58 +125,4 @@ private function getKeywordIds(array $keywords): array

return $connection->fetchCol($select);
}

/**
* Deletes obsolete asset keywords links
*
* @param array $newKeywords
* @param int $assetId
* @throws CouldNotDeleteException
*/
private function deleteObsoleteAssetKeywords(array $newKeywords, int $assetId): void
{
$oldKeywordData = $this->getAssetsKeywordsInterface->execute([$assetId]);

if (empty($newKeywords) || empty($oldKeywordData)) {
return;
}

$oldKeywordData = $this->getAssetsKeywordsInterface->execute([$assetId]);
$oldKeywords = $oldKeywordData[$assetId]->getKeywords();

foreach ($oldKeywords as $oldKeyword) {
if (!in_array($oldKeyword->getKeyword(), $newKeywords)) {
$obsoleteKeywords[] = $oldKeyword->getKeyword();
}
}

if (empty($obsoleteKeywords)) {
return;
}

$obsoleteKeywordIds = $this->getKeywordIds($obsoleteKeywords);

try {
/** @var Mysql $connection */
$connection = $this->resourceConnection->getConnection();
$connection->delete(
$connection->getTableName(
self::TABLE_ASSET_KEYWORD
),
[
'keyword_id in (?)' => $obsoleteKeywordIds,
'asset_id = ?' => $assetId
]
);
} catch (\Exception $exception) {
$this->logger->critical($exception);
$failedAssetId = $assetId;
}

if (!empty($failedAssetId)) {
throw new CouldNotDeleteException(
__('Could not delete obsolete keyword relation for asset id: %id', ['id' => $assetId])
);
}
}
}

0 comments on commit d81d262

Please sign in to comment.