Skip to content

Commit

Permalink
Add support for fields parameter in Search and Admin APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
const-cloudinary committed Nov 29, 2023
1 parent 82ba9bd commit 237ee1d
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 33 deletions.
75 changes: 44 additions & 31 deletions src/Api/Admin/AssetsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Cloudinary\Asset\AssetType;
use Cloudinary\Asset\DeliveryType;
use Cloudinary\Asset\ModerationStatus;
use Cloudinary\StringUtils;

/**
* Enables you to manage the assets in your cloud.
Expand Down Expand Up @@ -58,19 +59,9 @@ public function assets($options = [])
$uri = [ApiEndPoint::ASSETS, $assetType];
ArrayUtils::appendNonEmpty($uri, ArrayUtils::get($options, DeliveryType::KEY));

$params = ArrayUtils::whitelist(
$options,
[
'next_cursor',
'max_results',
'prefix',
'tags',
'context',
'moderations',
'direction',
'start_at',
'metadata',
]
$params = array_merge(
self::prepareListAssetsParams($options),
ArrayUtils::whitelist($options, ['prefix', 'direction'])
);

return $this->apiClient->get($uri, $params);
Expand All @@ -93,10 +84,7 @@ public function assetsByTag($tag, $options = [])
{
$assetType = ArrayUtils::get($options, AssetType::KEY, AssetType::IMAGE);
$uri = [ApiEndPoint::ASSETS, $assetType, 'tags', $tag];
$params = ArrayUtils::whitelist(
$options,
['next_cursor', 'max_results', 'tags', 'context', 'moderations', 'direction', 'metadata']
);
$params = self::prepareListAssetsParams($options);

return $this->apiClient->get($uri, $params);
}
Expand All @@ -121,10 +109,7 @@ public function assetsByContext($key, $value = null, $options = [])
{
$assetType = ArrayUtils::get($options, AssetType::KEY, AssetType::IMAGE);
$uri = [ApiEndPoint::ASSETS, $assetType, 'context'];
$params = ArrayUtils::whitelist(
$options,
['next_cursor', 'max_results', 'tags', 'context', 'moderations', 'direction', 'metadata']
);
$params = self::prepareListAssetsParams($options);
$params['key'] = $key;
$params['value'] = $value;

Expand All @@ -150,10 +135,7 @@ public function assetsByModeration($kind, $status, $options = [])
$assetType = ArrayUtils::get($options, AssetType::KEY, AssetType::IMAGE);
$uri = [ApiEndPoint::ASSETS, $assetType, 'moderations', $kind, $status];

$params = ArrayUtils::whitelist(
$options,
['next_cursor', 'max_results', 'tags', 'context', 'moderations', 'direction', 'metadata']
);
$params = self::prepareListAssetsParams($options);

return $this->apiClient->get($uri, $params);
}
Expand All @@ -175,7 +157,7 @@ public function assetsByIds($publicIds, $options = [])
$type = ArrayUtils::get($options, DeliveryType::KEY, DeliveryType::UPLOAD);
$uri = [ApiEndPoint::ASSETS, $assetType, $type];

$params = ArrayUtils::whitelist($options, ['public_ids', 'tags', 'moderations', 'context']);
$params = self::prepareAssetsParams($options);
$params['public_ids'] = $publicIds;

return $this->apiClient->get($uri, $params);
Expand All @@ -196,7 +178,7 @@ public function assetsByAssetIds($assetIds, $options = [])
{
$uri = [ApiEndPoint::ASSETS, 'by_asset_ids'];

$params = ArrayUtils::whitelist($options, ['public_ids', 'tags', 'moderations', 'context']);
$params = self::prepareAssetsParams($options);
$params['asset_ids'] = $assetIds;

return $this->apiClient->get($uri, $params);
Expand All @@ -218,10 +200,7 @@ public function assetsByAssetFolder($assetFolder, $options = [])
{
$uri = [ApiEndPoint::ASSETS, 'by_asset_folder'];

$params = ArrayUtils::whitelist(
$options,
['next_cursor', 'max_results', 'tags', 'moderations', 'context']
);
$params = self::prepareListAssetsParams($options);
$params['asset_folder'] = $assetFolder;

return $this->apiClient->get($uri, $params);
Expand Down Expand Up @@ -678,4 +657,38 @@ protected static function prepareAssetDetailsParams($options)
]
);
}

/**
* Prepares optional parameters for assets* API calls.
*
* @param array $options Additional options.
*
* @return array Optional parameters
*
* @internal
*/
protected static function prepareAssetsParams($options)
{
$params = ArrayUtils::whitelist($options, ['tags', 'context', 'metadata', 'moderations']);
$params['fields'] = ApiUtils::serializeSimpleApiParam((ArrayUtils::get($options, 'fields')));

return $params;
}

/**
* Prepares optional parameters for assetsBy* API calls.
*
* @param array $options Additional options.
*
* @return array Optional parameters
*
* @internal
*/
protected static function prepareListAssetsParams($options)
{
return array_merge(
self::prepareAssetsParams($options),
ArrayUtils::whitelist($options, ['next_cursor', 'max_results', 'direction'])
);
}
}
7 changes: 6 additions & 1 deletion src/Api/Search/SearchQueryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ interface SearchQueryInterface
* @internal
*/
const WITH_FIELD = 'with_field';

/**
* @internal
*/
const FIELDS = 'fields';
/**
* @internal
*/
Expand All @@ -34,5 +39,5 @@ interface SearchQueryInterface
/**
* @internal
*/
const KEYS_WITH_UNIQUE_VALUES = [self::SORT_BY, self::AGGREGATE, self::WITH_FIELD];
const KEYS_WITH_UNIQUE_VALUES = [self::SORT_BY, self::AGGREGATE, self::WITH_FIELD, self::FIELDS];
}
19 changes: 19 additions & 0 deletions src/Api/Search/SearchQueryTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ trait SearchQueryTrait
self::SORT_BY => [],
self::AGGREGATE => [],
self::WITH_FIELD => [],
self::FIELDS => [],
];

/**
Expand Down Expand Up @@ -129,6 +130,24 @@ public function withField($value)
return $this;
}

/**
* The list of the fields to include for each asset in the response.
*
* @param array|string $fields The fields' names.
*
* @return $this
*
* @api
*/
public function fields($fields)
{
foreach (ArrayUtils::build($fields) as $field) {
$this->query[self::FIELDS][$field] = $field;
}

return $this;
}

/**
* Sets the search query.
*
Expand Down
12 changes: 12 additions & 0 deletions tests/Integration/Admin/Assets/ListAssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,18 @@ public function testListRawUploadedFiles()
self::assertValidAsset($result['resources'][0], [AssetType::KEY => AssetType::RAW]);
}

/**
* Get specific fields.
*/
public function testListImagesFields()
{
$result = self::$adminApi->assets(['fields' => ['tags', 'secure_url']]);

self::assertArrayHasKey('tags', $result['resources'][0]);
self::assertArrayHasKey('secure_url', $result['resources'][0]);
self::assertArrayNotHasKey('url', $result['resources'][0]);
}

/**
* Get a single uploaded asset with a given ID passed as a string.
*/
Expand Down
50 changes: 50 additions & 0 deletions tests/Unit/Admin/AssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,56 @@ final class AssetsTest extends UnitTestCase
{
use RequestAssertionsTrait;


/**
* @return array[]
*/
public function listAssetsFieldsDataProvider()
{
return [
[
'options' => [
'fields' => ['tags', 'secure_url'],
],
'url' => '/resources/image',
'queryParams' => [
'fields' => 'tags,secure_url',
],
],
[
'options' => [
'fields' => 'context,url',
],
'url' => '/resources/image',
'queryParams' => [
'fields' => 'context,url',
],
],
[
'options' => [
'fields' => "",
],
'url' => '/resources/image',
'queryParams' => [],
],
];
}

/**
* Test list assets fields serialization.
*
* @dataProvider listAssetsFieldsDataProvider
*/
public function testListAssetFields($options, $url, $queryParams)
{
$mockAdminApi = new MockAdminApi();
$mockAdminApi->assets($options);
$lastRequest = $mockAdminApi->getMockHandler()->getLastRequest();

self::assertRequestUrl($lastRequest, $url);
self::assertRequestQueryStringSubset($lastRequest, $queryParams);
}

/**
* @return array[]
*/
Expand Down
8 changes: 7 additions & 1 deletion tests/Unit/Search/SearchApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Cloudinary\Test\Helpers\MockSearchFoldersApi;
use Cloudinary\Test\Helpers\MockSearchApi;
use Cloudinary\Test\Helpers\RequestAssertionsTrait;
use Cloudinary\Test\Unit\Asset\AssetTestCase;
use Cloudinary\Test\Unit\UnitTestCase;

/**
Expand Down Expand Up @@ -44,6 +43,9 @@ public function testExecuteWithParams()
->aggregate('resource_type')
->withField('tags')
->withField('image_metadata')
->fields(['tags', 'context'])
->fields('metadata')
->fields('tags')
->execute();
$lastRequest = $mockSearchApi->getMockHandler()->getLastRequest();

Expand All @@ -56,6 +58,7 @@ public function testExecuteWithParams()
],
'aggregate' => ['format', 'resource_type'],
'with_field' => ['tags', 'image_metadata'],
'fields' => ['tags', 'context', 'metadata'],
'expression' => 'format:png',
'max_results' => 10,
'next_cursor' => self::NEXT_CURSOR,
Expand Down Expand Up @@ -84,6 +87,8 @@ public function testShouldNotDuplicateValues()
->withField('context')
->withField('context')
->withField('tags')
->fields(['tags', 'context'])
->fields('tags')
->execute();
$lastRequest = $mockSearchApi->getMockHandler()->getLastRequest();

Expand All @@ -96,6 +101,7 @@ public function testShouldNotDuplicateValues()
],
'aggregate' => ['format', 'resource_type'],
'with_field' => ['context', 'tags'],
'fields' => ['tags', 'context'],
]
);
}
Expand Down

0 comments on commit 237ee1d

Please sign in to comment.