Skip to content

Commit bef4df8

Browse files
authored
ENGCOM-7827: Introduce SearchAssets service #29071
2 parents ffe6c24 + db862ab commit bef4df8

File tree

6 files changed

+344
-0
lines changed

6 files changed

+344
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
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\MediaGallery\Model\ResourceModel;
9+
10+
use Magento\Framework\Exception\LocalizedException;
11+
use Magento\Framework\App\ResourceConnection;
12+
use Psr\Log\LoggerInterface;
13+
use Magento\Framework\Api\Search\SearchResultInterface;
14+
use Magento\Framework\Api\SearchCriteriaInterface;
15+
use Magento\Framework\Api\Search\SearchResultFactory;
16+
use Magento\Framework\DB\Select;
17+
use Magento\MediaGalleryApi\Api\Data\AssetInterface;
18+
19+
/**
20+
* Get assets data by searchCriteria
21+
*/
22+
class GetAssetsBySearchCriteria
23+
{
24+
private const TABLE_MEDIA_GALLERY_ASSET = 'media_gallery_asset';
25+
26+
/**
27+
* @var ResourceConnection
28+
*/
29+
private $resourceConnection;
30+
31+
/**
32+
* @var SearchResultFactory
33+
*/
34+
private $searchResultFactory;
35+
36+
/**
37+
* @var LoggerInterface
38+
*/
39+
private $logger;
40+
41+
/**
42+
* @param SearchResultFactory $searchResultFactory
43+
* @param ResourceConnection $resourceConnection
44+
* @param LoggerInterface $logger
45+
*/
46+
public function __construct(
47+
SearchResultFactory $searchResultFactory,
48+
ResourceConnection $resourceConnection,
49+
LoggerInterface $logger
50+
) {
51+
$this->searchResultFactory = $searchResultFactory;
52+
$this->resourceConnection = $resourceConnection;
53+
$this->logger = $logger;
54+
}
55+
56+
/**
57+
* Retrieve assets data from database
58+
*
59+
* @param SearchCriteriaInterface $searchCriteria
60+
* @return SearchResultInterface
61+
*/
62+
public function execute(SearchCriteriaInterface $searchCriteria): SearchResultInterface
63+
{
64+
$searchResult = $this->searchResultFactory->create();
65+
$fields = [];
66+
$conditions = [];
67+
68+
foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
69+
foreach ($filterGroup->getFilters() as $filter) {
70+
$condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
71+
$fields[] = $filter->getField();
72+
73+
if ($condition === 'fulltext') {
74+
$condition = 'like';
75+
$filter->setValue('%' . $filter->getValue() . '%');
76+
}
77+
78+
$conditions[] = [$condition => $filter->getValue()];
79+
}
80+
}
81+
82+
if ($fields) {
83+
$resultCondition = $this->getResultCondition($fields, $conditions);
84+
$select = $this->resourceConnection->getConnection()->select()
85+
->from(
86+
$this->resourceConnection->getTableName(self::TABLE_MEDIA_GALLERY_ASSET)
87+
)
88+
->where($resultCondition, null, Select::TYPE_CONDITION);
89+
90+
if ($searchCriteria->getPageSize() || $searchCriteria->getCurrentPage()) {
91+
$select->limit(
92+
$searchCriteria->getPageSize(),
93+
$searchCriteria->getCurrentPage() * $searchCriteria->getPageSize()
94+
);
95+
}
96+
97+
$data = $this->resourceConnection->getConnection()->fetchAll($select);
98+
}
99+
100+
$searchResult->setSearchCriteria($searchCriteria);
101+
$searchResult->setItems($data);
102+
103+
return $searchResult;
104+
}
105+
106+
/**
107+
* Get conditions data by searchCriteria
108+
*
109+
* @param string|array $field
110+
* @param null|string|array $condition
111+
*/
112+
public function getResultCondition($field, $condition = null)
113+
{
114+
$resourceConnection = $this->resourceConnection->getConnection();
115+
if (is_array($field)) {
116+
$conditions = [];
117+
foreach ($field as $key => $value) {
118+
$conditions[] = $resourceConnection->prepareSqlCondition(
119+
$resourceConnection->quoteIdentifier($value),
120+
isset($condition[$key]) ? $condition[$key] : null
121+
);
122+
}
123+
124+
$resultCondition = '(' . implode(') ' . Select::SQL_OR . ' (', $conditions) . ')';
125+
} else {
126+
$resultCondition = $resourceConnection->prepareSqlCondition(
127+
$resourceConnection->quoteIdentifier($field),
128+
$condition
129+
);
130+
}
131+
return $resultCondition;
132+
}
133+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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\MediaGallery\Model;
9+
10+
use Magento\Framework\Exception\LocalizedException;
11+
use Magento\MediaGalleryApi\Api\Data\AssetInterfaceFactory;
12+
use Psr\Log\LoggerInterface;
13+
use Magento\Framework\Api\SearchCriteriaInterface;
14+
use Magento\MediaGallery\Model\ResourceModel\GetAssetsBySearchCriteria;
15+
use Magento\MediaGalleryApi\Api\SearchAssetsInterface;
16+
17+
/**
18+
* Get media assets by searchCriteria
19+
*/
20+
class SearchAssets implements SearchAssetsInterface
21+
{
22+
/**
23+
* @var GetAssetsBySearchCriteria
24+
*/
25+
private $getAssetsBySearchCriteria;
26+
27+
/**
28+
* @var LoggerInterface
29+
*/
30+
private $logger;
31+
32+
/**
33+
* @var AssetInterfaceFactory
34+
*/
35+
private $mediaAssetFactory;
36+
37+
/**
38+
* @param GetAssetsBySearchCriteria $getAssetsBySearchCriteria
39+
* @param AssetInterfaceFactory $mediaAssetFactory
40+
* @param LoggerInterface $logger
41+
*/
42+
public function __construct(
43+
GetAssetsBySearchCriteria $getAssetsBySearchCriteria,
44+
AssetInterfaceFactory $mediaAssetFactory,
45+
LoggerInterface $logger
46+
) {
47+
$this->getAssetsBySearchCriteria = $getAssetsBySearchCriteria;
48+
$this->mediaAssetFactory = $mediaAssetFactory;
49+
$this->logger = $logger;
50+
}
51+
52+
/**
53+
* @inheritdoc
54+
*/
55+
public function execute(SearchCriteriaInterface $searchCriteria): array
56+
{
57+
$assets = [];
58+
try {
59+
foreach ($this->getAssetsBySearchCriteria->execute($searchCriteria)->getItems() as $assetData) {
60+
$assets[] = $this->mediaAssetFactory->create(
61+
[
62+
'id' => $assetData['id'],
63+
'path' => $assetData['path'],
64+
'title' => $assetData['title'],
65+
'description' => $assetData['description'],
66+
'source' => $assetData['source'],
67+
'hash' => $assetData['hash'],
68+
'contentType' => $assetData['content_type'],
69+
'width' => $assetData['width'],
70+
'height' => $assetData['height'],
71+
'size' => $assetData['size'],
72+
'createdAt' => $assetData['created_at'],
73+
'updatedAt' => $assetData['updated_at'],
74+
]
75+
);
76+
}
77+
} catch (\Exception $exception) {
78+
$this->logger->critical($exception);
79+
throw new LocalizedException(__('Could not retrieve media assets'), $exception->getMessage());
80+
}
81+
return $assets;
82+
}
83+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
<preference for="Magento\MediaGalleryApi\Api\SaveAssetsInterface" type="Magento\MediaGallery\Model\ResourceModel\SaveAssets"/>
3030
<preference for="Magento\MediaGalleryApi\Api\GetAssetsKeywordsInterface" type="Magento\MediaGallery\Model\ResourceModel\Keyword\GetAssetsKeywords"/>
3131
<preference for="Magento\MediaGalleryApi\Api\SaveAssetsKeywordsInterface" type="Magento\MediaGallery\Model\ResourceModel\Keyword\SaveAssetsKeywords"/>
32+
<preference for="Magento\MediaGalleryApi\Api\SearchAssetsInterface" type="Magento\MediaGallery\Model\SearchAssets"/>
3233

3334
<type name="Magento\Cms\Model\Wysiwyg\Images\Storage">
3435
<plugin name="media_gallery_image_remove_metadata_after_wysiwyg" type="Magento\MediaGallery\Plugin\Wysiwyg\Images\Storage"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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\MediaGalleryApi\Api;
9+
10+
use Magento\Framework\Api\Search\SearchResultInterface;
11+
use Magento\Framework\Api\SearchCriteriaInterface;
12+
use Magento\Framework\Exception\LocalizedException;
13+
14+
/**
15+
* Search media gallery assets by search criteria
16+
*/
17+
interface SearchAssetsInterface
18+
{
19+
/**
20+
* Search media gallery assets
21+
*
22+
* @param SearchCriteriaInterface $searchCriteria
23+
* @return AssetsSearchResultInterface[]
24+
* @throws LocalizedException
25+
*/
26+
public function execute(SearchCriteriaInterface $searchCriteria): array;
27+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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\MediaGallery\Model;
9+
10+
use Magento\Framework\Api\FilterBuilder;
11+
use Magento\Framework\Api\Search\FilterGroupBuilder;
12+
use Magento\Framework\Api\SearchCriteriaBuilder;
13+
use Magento\MediaGalleryApi\Api\SearchAssetsInterface;
14+
use Magento\TestFramework\Helper\Bootstrap;
15+
use PHPUnit\Framework\TestCase;
16+
17+
/**
18+
* Verify SearchAssets By searchCriteria
19+
*/
20+
class SearchAssetsTest extends TestCase
21+
{
22+
private const FIXTURE_ASSET_PATH = 'testDirectory/path.jpg';
23+
24+
/**
25+
* @var SearchAssetsInterfcae
26+
*/
27+
private $searchAssets;
28+
29+
/**
30+
* @var SearchCriteriaBuilder
31+
*/
32+
private $searchCriteriaBuilder;
33+
34+
/**
35+
* @var FilterGroupBuilder
36+
*/
37+
private $filterGroupBuilder;
38+
39+
/**
40+
* @var FilterBuilder
41+
*/
42+
private $filterBuilder;
43+
44+
/**
45+
* @inheritdoc
46+
*/
47+
protected function setUp(): void
48+
{
49+
$this->filterBuilder = Bootstrap::getObjectManager()->get(FilterBuilder::class);
50+
$this->filterGroupBuilder = Bootstrap::getObjectManager()->get(FilterGroupBuilder::class);
51+
$this->searchCriteriaBuilder = Bootstrap::getObjectManager()->get(SearchCriteriaBuilder::class);
52+
$this->searchAssets = Bootstrap::getObjectManager()->get(SearchAssetsInterface::class);
53+
}
54+
55+
/**
56+
* Verify search asstes by searching with search criteria
57+
*
58+
* @dataProvider searchCriteriaProvider
59+
* @magentoDataFixture Magento/MediaGallery/_files/media_asset.php
60+
*/
61+
public function testExecute(array $searchCriteriaData): void
62+
{
63+
$titleFilter = $this->filterBuilder->setField($searchCriteriaData['field'])
64+
->setConditionType($searchCriteriaData['conditionType'])
65+
->setValue($searchCriteriaData['value'])
66+
->create();
67+
$searchCriteria = $this->searchCriteriaBuilder
68+
->setFilterGroups([$this->filterGroupBuilder->setFilters([$titleFilter])->create()])
69+
->create();
70+
71+
$assets = $this->searchAssets->execute($searchCriteria);
72+
73+
$this->assertCount(1, $assets);
74+
$this->assertEquals($assets[0]->getPath(), self::FIXTURE_ASSET_PATH);
75+
}
76+
77+
/**
78+
* Search criteria params provider
79+
*
80+
* @return array
81+
*/
82+
public function searchCriteriaProvider(): array
83+
{
84+
return [
85+
[
86+
['field' => 'id', 'conditionType' => 'eq', 'value' => 2020],
87+
],
88+
[
89+
['field' => 'title', 'conditionType' => 'fulltext', 'value' => 'Img'],
90+
],
91+
[
92+
['field' => 'content_type', 'conditionType' => 'eq', 'value' => 'image']
93+
],
94+
[
95+
['field' => 'description', 'conditionType' => 'fulltext', 'value' => 'description']
96+
]
97+
];
98+
}
99+
}

dev/tests/integration/testsuite/Magento/MediaGallery/_files/media_asset.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
[
1919
'id' => 2020,
2020
'path' => 'testDirectory/path.jpg',
21+
'description' => 'Description of an image',
2122
'contentType' => 'image',
2223
'title' => 'Img',
2324
'source' => 'Local',

0 commit comments

Comments
 (0)