Skip to content

Commit 8ad6be2

Browse files
committed
- add bulk operations
- add asset-content link entity - refactoring
1 parent c1480f3 commit 8ad6be2

File tree

11 files changed

+436
-18
lines changed

11 files changed

+436
-18
lines changed

app/code/Magento/MediaContent/Model/Content/Config.php

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/**
1313
* Media content configuration
1414
*/
15-
class Config
15+
class Config implements ConfigInterface
1616
{
1717
private const XML_PATH_SEARCH_PATTERNS = 'search/patterns';
1818

@@ -30,24 +30,12 @@ public function __construct(DataInterface $data)
3030
}
3131

3232
/**
33-
* Get config value by key.
34-
*
35-
* @param string|null $key
36-
* @param string|null $default
37-
* @return array
38-
*/
39-
public function get($key = null, $default = null)
40-
{
41-
return $this->data->get($key, $default);
42-
}
43-
44-
/**
45-
* Retrieve search regexp patterns for finding media asset paths within content
33+
* Retrieve search RegExp patterns for finding media asset paths within content
4634
*
4735
* @return array
4836
*/
4937
public function getSearchPatterns(): array
5038
{
51-
return $this->get(self::XML_PATH_SEARCH_PATTERNS);
39+
return $this->data->get(self::XML_PATH_SEARCH_PATTERNS);
5240
}
53-
}
41+
}

app/code/Magento/MediaContent/Model/Content/Config/Converter.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,19 @@
1414
*/
1515
class Converter implements ConverterInterface
1616
{
17+
/*
18+
* Search tag name
19+
*/
1720
private const SEARCH_TAG_NAME = 'search';
21+
22+
/**
23+
* Patterns tag name
24+
*/
1825
private const PATTERNS_TAG_NAME = 'patterns';
26+
27+
/**
28+
* Pattern tag name
29+
*/
1930
private const PATTERN_TAG_NAME = 'pattern';
2031

2132
/**
@@ -29,7 +40,7 @@ public function convert($source) : array
2940
$result = [];
3041

3142
if (!$source instanceof \DOMDocument) {
32-
return $result;
43+
throw new \InvalidArgumentException('The source should be instance of DOMDocument');
3344
}
3445

3546
foreach ($source->getElementsByTagName(self::SEARCH_TAG_NAME) as $search) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\MediaContent\Model\Content;
8+
9+
/**
10+
* Interface for Media content Config.
11+
*/
12+
interface ConfigInterface
13+
{
14+
/**
15+
* Retrieve search regexp patterns for finding media asset paths within content
16+
*
17+
* @return array
18+
*/
19+
public function getSearchPatterns() : array;
20+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
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\MediaContent\Model;
9+
10+
use Magento\Framework\Model\AbstractExtensibleModel;
11+
use Magento\Framework\Model\Context;
12+
use Magento\Framework\Registry;
13+
use Magento\Framework\Api\ExtensionAttributesFactory;
14+
use Magento\Framework\Api\AttributeValueFactory;
15+
use Magento\Framework\Model\ResourceModel\AbstractResource;
16+
use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface;
17+
use Magento\Framework\Data\Collection\AbstractDb;
18+
use Magento\MediaContentApi\Api\Data\ContentIdentityInterfaceFactory;
19+
20+
/**
21+
* Relation of the media asset to the media content
22+
*/
23+
class ContentAssetLink extends AbstractExtensibleModel implements ContentAssetLinkInterface
24+
{
25+
private const ASSET_ID = 'asset_id';
26+
private const ENTITY_TYPE = 'entity_type';
27+
private const ENTITY_ID = 'entity_id';
28+
private const FIELD = 'field';
29+
30+
/**
31+
* @var ContentIdentityInterfaceFactory
32+
*/
33+
private $contentIdentityFactory;
34+
35+
/**
36+
* @param \Magento\Framework\Model\Context $context
37+
* @param \Magento\Framework\Registry $registry
38+
* @param ExtensionAttributesFactory $extensionFactory
39+
* @param AttributeValueFactory $customAttributeFactory
40+
* @param ContentIdentityInterfaceFactory $contentIdentityFactory
41+
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
42+
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
43+
* @param array $data
44+
*/
45+
public function __construct(
46+
Context $context,
47+
Registry $registry,
48+
ExtensionAttributesFactory $extensionFactory,
49+
AttributeValueFactory $customAttributeFactory,
50+
ContentIdentityInterfaceFactory $contentIdentityFactory,
51+
AbstractResource $resource = null,
52+
AbstractDb $resourceCollection = null,
53+
array $data = []
54+
) {
55+
$this->contentIdentityFactory = $contentIdentityFactory;
56+
parent::__construct(
57+
$context,
58+
$registry,
59+
$extensionFactory,
60+
$customAttributeFactory,
61+
$resource,
62+
$resourceCollection,
63+
$data
64+
);
65+
}
66+
67+
/**
68+
* @inheritdoc
69+
*/
70+
public function getAssetId(): int
71+
{
72+
return (int) $this->getData(self::ASSET_ID);
73+
}
74+
75+
/**
76+
* @inheritdoc
77+
*/
78+
public function getContentId(): ContentIdentityInterface
79+
{
80+
return $this->contentIdentityFactory->create(['data' => [
81+
self::ENTITY_TYPE => $this->getData(self::ENTITY_TYPE),
82+
self::ENTITY_ID => $this->getData(self::ENTITY_TYPE),
83+
self::FIELD => $this->getData(self::FIELD)
84+
]]);
85+
}
86+
87+
/**
88+
* @inheritdoc
89+
*/
90+
public function getField(): string
91+
{
92+
return (string) $this->getData(self::FIELD);
93+
}
94+
95+
/**
96+
* @inheritdoc
97+
*/
98+
public function getExtensionAttributes(): ContentAssetLinkExtensionInterface
99+
{
100+
return $this->_getExtensionAttributes();
101+
}
102+
103+
/**
104+
* @inheritdoc
105+
*/
106+
public function setExtensionAttributes(ContentAssetLinkExtensionInterface $extensionAttributes): void
107+
{
108+
$this->_setExtensionAttributes($extensionAttributes);
109+
}
110+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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\MediaContent\Model;
9+
10+
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Framework\Exception\CouldNotDeleteException;
12+
use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface;
13+
use Magento\MediaContentApi\Api\DeleteContentAssetLinksInterface;
14+
use Psr\Log\LoggerInterface;
15+
16+
/**
17+
* Used to unassign relation of the media asset to the media content where the media asset is used
18+
*/
19+
class DeleteContentAssetLinks implements DeleteContentAssetLinksInterface
20+
{
21+
private const MEDIA_CONTENT_ASSET_TABLE_NAME = 'media_content_asset';
22+
private const ASSET_ID = 'asset_id';
23+
private const ENTITY_TYPE = 'entity_type';
24+
private const ENTITY_ID = 'entity_id';
25+
private const FIELD = 'field';
26+
27+
/**
28+
* @var ResourceConnection
29+
*/
30+
private $resourceConnection;
31+
32+
/**
33+
* @var LoggerInterface
34+
*/
35+
private $logger;
36+
37+
/**
38+
* @param ResourceConnection $resourceConnection
39+
* @param LoggerInterface $logger
40+
*/
41+
public function __construct(ResourceConnection $resourceConnection, LoggerInterface $logger)
42+
{
43+
$this->resourceConnection = $resourceConnection;
44+
$this->logger = $logger;
45+
}
46+
47+
/**
48+
* Remove relation between the media asset and the content. I.e media asset no longer part of the content
49+
*
50+
* @param ContentAssetLinkInterface[] $contentAssetsLinks
51+
* @throws CouldNotDeleteException
52+
*/
53+
public function execute(array $contentAssetsLinks): void
54+
{
55+
$failedLinks = [];
56+
foreach ($contentAssetsLinks as $contentAssetLink) {
57+
try {
58+
$connection = $this->resourceConnection->getConnection();
59+
$tableName = $this->resourceConnection->getTableName(self::MEDIA_CONTENT_ASSET_TABLE_NAME);
60+
$connection->delete(
61+
$tableName,
62+
[
63+
self::ASSET_ID . ' = ?' => $contentAssetLink->getAssetId(),
64+
self::ENTITY_TYPE . ' = ?' => $contentAssetLink->getContentId()->getEntityType(),
65+
self::ENTITY_ID . ' = ?' => $contentAssetLink->getContentId()->getEntityId(),
66+
self::FIELD . ' = ?' => $contentAssetLink->getField()
67+
]
68+
);
69+
} catch (\Exception $exception) {
70+
$this->logger->critical($exception);
71+
$failedLinks[] = self::ASSET_ID . '=' . $contentAssetLink->getAssetId() .
72+
self::ENTITY_TYPE . ' = ' . $contentAssetLink->getContentId()->getEntityType() .
73+
self::ENTITY_ID . ' = ' . $contentAssetLink->getContentId()->getEntityId() .
74+
self::FIELD . ' = ' . $contentAssetLink->getField();
75+
}
76+
}
77+
78+
if (!empty($failedLinks)) {
79+
throw new CouldNotDeleteException(
80+
__(
81+
'An error occurred at deleting link between the media asset and media content. Links: %links',
82+
implode(' ,', $failedLinks)
83+
)
84+
);
85+
}
86+
}
87+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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\MediaContent\Model;
9+
10+
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Framework\Exception\CouldNotSaveException;
12+
use Magento\MediaContentApi\Api\SaveContentAssetLinksInterface;
13+
use Magento\MediaContentApi\Api\Data\ContentIdentityInterface;
14+
use Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface;
15+
use Psr\Log\LoggerInterface;
16+
17+
/**
18+
* Used for saving relation between the media asset and media content where the media asset is used
19+
*/
20+
class SaveContentAssetLinks implements SaveContentAssetLinksInterface
21+
{
22+
private const MEDIA_CONTENT_ASSET_TABLE_NAME = 'media_content_asset';
23+
private const ASSET_ID = 'asset_id';
24+
private const ENTITY_TYPE = 'entity_type';
25+
private const ENTITY_ID = 'entity_id';
26+
private const FIELD = 'field';
27+
28+
/**
29+
* @var ResourceConnection
30+
*/
31+
private $resourceConnection;
32+
33+
/**
34+
* @var LoggerInterface
35+
*/
36+
private $logger;
37+
38+
/**
39+
* @param ResourceConnection $resourceConnection
40+
* @param LoggerInterface $logger
41+
*/
42+
public function __construct(ResourceConnection $resourceConnection, LoggerInterface $logger)
43+
{
44+
$this->resourceConnection = $resourceConnection;
45+
$this->logger = $logger;
46+
}
47+
48+
/**
49+
* Save a media asset to content relation. Should be executed when media assets is added to the content
50+
*
51+
* @param ContentAssetLinkInterface[] $contentAssetLinks
52+
* @throws \Magento\Framework\Exception\CouldNotSaveException
53+
*/
54+
public function execute(array $contentAssetsLinks): void
55+
{
56+
try {
57+
$connection = $this->resourceConnection->getConnection();
58+
$tableName = $this->resourceConnection->getTableName(self::MEDIA_CONTENT_ASSET_TABLE_NAME);
59+
$data = [];
60+
61+
foreach ($contentAssetsLinks as $contentAssetLink) {
62+
$data[] = [
63+
self::ASSET_ID => $contentAssetLink->getAssetId(),
64+
self::ENTITY_TYPE => $contentAssetLink->getContentId()->getEntityType(),
65+
self::ENTITY_ID => $contentAssetLink->getContentId()->getEntityId(),
66+
self::FIELD => $contentAssetLink->getField()
67+
];
68+
}
69+
70+
$connection->insertMultiple($tableName, $data);
71+
} catch (\Exception $exception) {
72+
$this->logger->critical($exception);
73+
throw new CouldNotSaveException(
74+
__('An error occurred while saving relation between media asset and media content.'),
75+
$exception
76+
);
77+
}
78+
}
79+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
<preference for="Magento\MediaContentApi\Api\GetContentWithAssetsInterface" type="Magento\MediaContent\Model\GetContentWithAssets"/>
1313
<preference for="Magento\MediaContentApi\Api\ExtractAssetsFromContentInterface" type="Magento\MediaContent\Model\ExtractAssetsFromContent"/>
1414
<preference for="Magento\MediaContentApi\Api\UpdateRelationsInterface" type="Magento\MediaContent\Model\UpdateRelations"/>
15+
<preference for="Magento\MediaContentApi\Api\DeleteContentAssetLinksInterface" type="Magento\MediaContent\Model\DeleteContentAssetLinks"/>
16+
<preference for="Magento\MediaContentApi\Api\SaveContentAssetLinksInterface" type="Magento\MediaContent\Model\SaveContentAssetLinks"/>
1517
<preference for="Magento\MediaContentApi\Api\Data\ContentIdentityInterface" type="Magento\MediaContent\Model\ContentIdentity"/>
18+
<preference for="Magento\MediaContentApi\Api\Data\ContentAssetLinkInterface" type="Magento\MediaContent\Model\ContentAssetLink"/>
19+
<preference for="Magento\MediaContent\Model\Content\ConfigInterface" type="Magento\MediaContent\Model\Content\Config"/>
1620
<type name="Magento\MediaGalleryApi\Model\Asset\Command\DeleteByPathInterface">
1721
<plugin name="remove_media_content_after_asset_is_removed_by_path" type="Magento\MediaContent\Model\MediaGalleryAssetDeleteByPath" />
1822
</type>

0 commit comments

Comments
 (0)