Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for analyze API #398

Merged
merged 1 commit into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/Api/Admin/AdminApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace Cloudinary\Api\Admin;

use Cloudinary\Api\ApiClient;
use Cloudinary\Configuration\Configuration;

/**
* Enables Cloudinary Admin API functionality.
Expand All @@ -31,12 +32,18 @@ class AdminApi
use UploadMappingsTrait;
use MiscTrait;
use MetadataFieldsTrait;
use AnalysisTrait;

/**
* @var ApiClient $apiClient The API client instance.
*/
protected $apiClient;

/**
* @var ApiClient $apiV2Client The API v2 client instance.
*/
protected $apiV2Client;

/**
* AdminApi constructor.
*
Expand All @@ -46,5 +53,10 @@ class AdminApi
public function __construct($configuration = null)
{
$this->apiClient = new ApiClient($configuration);

$apiV2Configuration = new Configuration($configuration);
$apiV2Configuration->api->apiVersion = '2';

$this->apiV2Client = new ApiClient($apiV2Configuration);
}
}
63 changes: 63 additions & 0 deletions src/Api/Admin/AnalysisTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
/**
* This file is part of the Cloudinary PHP package.
*
* (c) Cloudinary
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Cloudinary\Api\Admin;

use Cloudinary\Api\ApiClient;
use Cloudinary\Api\ApiResponse;
use GuzzleHttp\Promise\PromiseInterface;

/**
* Represents Analysis API methods.
*
* @property ApiClient $apiV2Client Defined in AdminApi class.
*
* @api
*/
trait AnalysisTrait
{
/**
* Analyzes an asset with the requested analysis type.
*
* @param string $inputType The type of input for the asset to analyze ('uri').
* @param string $analysisType The type of analysis to run ('google_tagging', 'captioning', 'fashion').
* @param string $uri The URI of the asset to analyze.
*
* @return ApiResponse
*
* @see AdminApi::analyzeAsync()
*
* @see https://cloudinary.com/documentation/media_analyzer_api_reference
*/
public function analyze($inputType, $analysisType, $uri = null)
{
return $this->analyzeAsync($inputType, $analysisType, $uri)->wait();
}

/**
* Analyzes an asset with the requested analysis type asynchronously.
*
* @param string $inputType The type of input for the asset to analyze ('uri').
* @param string $analysisType The type of analysis to run ('google_tagging', 'captioning', 'fashion').
* @param string $uri The URI of the asset to analyze.
*
* @return PromiseInterface
*
* @see https://cloudinary.com/documentation/media_analyzer_api_reference
*/
public function analyzeAsync($inputType, $analysisType, $uri = null)
{
$endPoint = [ApiEndPoint::ANALYSIS, 'analyze'];

$params = ['input_type' => $inputType, 'analysis_type' => $analysisType, 'uri' => $uri];

return $this->apiV2Client->postJsonAsync($endPoint, $params);
}
}
1 change: 1 addition & 0 deletions src/Api/Admin/ApiEndPoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ class ApiEndPoint
const UPLOAD_PRESETS = 'upload_presets';
const UPLOAD_MAPPINGS = 'upload_mappings';
const METADATA_FIELDS = 'metadata_fields';
const ANALYSIS = 'analysis';
}
11 changes: 6 additions & 5 deletions src/Api/ApiClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public function __construct($configuration = null)

$this->configuration($configuration);

$this->baseUri = "{$this->api->uploadPrefix}/" . self::apiVersion() . "/{$this->cloud->cloudName}/";
$this->baseUri = "{$this->api->uploadPrefix}/" . self::apiVersion($this->api->apiVersion)
. "/{$this->cloud->cloudName}/";

$this->createHttpClient();
}
Expand Down Expand Up @@ -140,7 +141,7 @@ public function postFormAsync($endPoint, $formParams)
*/
public function postAndSignFormAsync($endPoint, $formParams)
{
if (!$this->cloud->oauthToken) {
if (! $this->cloud->oauthToken) {
ApiUtils::signRequest($formParams, $this->cloud);
}

Expand Down Expand Up @@ -240,7 +241,7 @@ public function postFileAsync($endPoint, $file, $parameters, $options = [])
{
$unsigned = ArrayUtils::get($options, 'unsigned');

if (!$this->cloud->oauthToken && !$unsigned) {
if (! $this->cloud->oauthToken && ! $unsigned) {
ApiUtils::signRequest($parameters, $this->cloud);
}

Expand Down Expand Up @@ -414,11 +415,11 @@ protected function buildHttpClientConfig()

if (isset($this->cloud->oauthToken)) {
$authConfig = [
'headers' => ['Authorization' => 'Bearer ' . $this->cloud->oauthToken]
'headers' => ['Authorization' => 'Bearer ' . $this->cloud->oauthToken],
];
} else {
$authConfig = [
'auth' => [$this->cloud->apiKey, $this->cloud->apiSecret]
'auth' => [$this->cloud->apiKey, $this->cloud->apiSecret],
];
}

Expand Down
13 changes: 5 additions & 8 deletions src/Api/BaseApiClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@ class BaseApiClient
{
use LoggerTrait;

/**
* @var string Cloudinary API version
*/
const API_VERSION = '1.1';

/**
* @var array Cloudinary API Error Classes mapping between http error codes and Cloudinary exceptions
*/
Expand Down Expand Up @@ -275,13 +270,15 @@ public function putJson($endPoint, $json)
/**
* Gets the API version string from the version.
*
* @param string $apiVersion The API version in the form Major.minor (for example: 1.1).
*
* @return string API version string
*
* @internal
*/
public static function apiVersion()
public static function apiVersion($apiVersion = ApiConfig::DEFAULT_API_VERSION)
{
return 'v' . str_replace('.', '_', self::API_VERSION);
return 'v' . str_replace('.', '_', $apiVersion);
}

/**
Expand Down Expand Up @@ -315,7 +312,7 @@ protected static function finalizeEndPoint($endPoint)
*/
protected function callAsync($method, $endPoint, $options)
{
$endPoint = self::finalizeEndPoint($endPoint);
$endPoint = self::finalizeEndPoint($endPoint);
$options['headers'] = ArrayUtils::mergeNonEmpty(
ArrayUtils::get($options, 'headers', []),
ArrayUtils::get($options, 'extra_headers', [])
Expand Down
2 changes: 1 addition & 1 deletion src/Api/Provisioning/AccountApiClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function init(ProvisioningConfiguration $configuration = null)
$this->baseUri = sprintf(
'%s/%s/%s/%s/%s/',
$this->api->uploadPrefix,
self::apiVersion(),
self::apiVersion($this->api->apiVersion),
self::PROVISIONING,
self::ACCOUNTS,
$configuration->provisioningAccount->accountId
Expand Down
10 changes: 10 additions & 0 deletions src/Configuration/ApiConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* Defines the global configuration when making requests to the Cloudinary API.
*
* @property string $uploadPrefix Used for changing default API host.
* @property string $apiVersion Used for changing default API version.
* @property int|float $timeout Describing the timeout of the request in seconds.
* Use 0 to wait indefinitely (the default value is 60 seconds).
* @property int|float $uploadTimeout Describing the timeout of the upload request in seconds.
Expand All @@ -27,11 +28,13 @@ class ApiConfig extends BaseConfigSection
const CONFIG_NAME = 'api';

const DEFAULT_UPLOAD_PREFIX = 'https://api.cloudinary.com';
const DEFAULT_API_VERSION = '1.1';
const DEFAULT_CHUNK_SIZE = 20000000; // bytes
const DEFAULT_TIMEOUT = 60; // seconds

// Supported parameters
const UPLOAD_PREFIX = 'upload_prefix'; // FIXME: rename it! (it is actually prefix for all API calls)
const API_VERSION = 'api_version';
const API_PROXY = 'api_proxy';
const CONNECTION_TIMEOUT = 'connection_timeout';
const TIMEOUT = 'timeout';
Expand All @@ -46,6 +49,13 @@ class ApiConfig extends BaseConfigSection
*/
protected $uploadPrefix;

/**
* Used for changing default API version.
*
* @var string
*/
protected $apiVersion;

/**
* Optional. Specifies a proxy through which to make calls to the Cloudinary API. Format: http://hostname:port.
*
Expand Down
7 changes: 7 additions & 0 deletions tests/Helpers/MockAdminApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
namespace Cloudinary\Test\Helpers;

use Cloudinary\Api\Admin\AdminApi;
use Cloudinary\Api\ApiClient;
use Cloudinary\Configuration\Configuration;

/**
* Class MockAdminApi
Expand All @@ -29,5 +31,10 @@ public function __construct($configuration = null)
parent::__construct($configuration);

$this->apiClient = new MockApiClient($configuration);

$apiV2Configuration = new Configuration($configuration);
$apiV2Configuration->api->apiVersion = '2';

$this->apiV2Client = new MockApiClient($apiV2Configuration);
}
}
4 changes: 4 additions & 0 deletions tests/Helpers/MockApiClientTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ static function ($options, $item) {
}
);
}

/**
* @return \string[][]
*/
public function getLastRequestHeaders()
{
return $this->mockHandler->getLastRequest()->getHeaders();
Expand Down
22 changes: 21 additions & 1 deletion tests/Helpers/MockApiTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,33 @@ public function getMockHandler()
return $this->getApiClient()->mockHandler;
}

/**
* Returns mock handler.
*
* @return MockHandler
*/
public function getV2MockHandler()
{
return $this->getApiV2Client()->mockHandler;
}

/**
* Returns a mock api client.
*
* @return MockApiClient
* @return \Cloudinary\Api\ApiClient|\Cloudinary\Api\UploadApiClient|MockApiClient
*/
public function getApiClient()
{
return $this->apiClient;
}

/**
* Returns a mock api client.
*
* @return \Cloudinary\Api\ApiClient|\Cloudinary\Api\UploadApiClient|MockApiClient
*/
public function getApiV2Client()
{
return $this->apiV2Client;
}
}
8 changes: 5 additions & 3 deletions tests/Helpers/RequestAssertionsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,14 @@ protected static function assertRequestFields(RequestInterface $request, $fields
* @param string $path
* @param string $message
*/
protected static function assertRequestUrl(RequestInterface $request, $path, $message = '')
protected static function assertRequestUrl(RequestInterface $request, $path, $message = '', $config = null)
{
$config = Configuration::instance();
if ($config == null) {
$config = Configuration::instance();
}

self::assertEquals(
'/' . ApiClient::apiVersion() . '/' . $config->cloud->cloudName . $path,
'/' . ApiClient::apiVersion($config->api->apiVersion) . '/' . $config->cloud->cloudName . $path,
$request->getUri()->getPath(),
$message
);
Expand Down
50 changes: 50 additions & 0 deletions tests/Unit/Admin/AnalysisTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/**
* This file is part of the Cloudinary PHP package.
*
* (c) Cloudinary
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Cloudinary\Test\Unit\Admin;

use Cloudinary\Api\Exception\ApiError;
use Cloudinary\Configuration\Configuration;
use Cloudinary\Test\Helpers\MockAdminApi;
use Cloudinary\Test\Helpers\RequestAssertionsTrait;
use Cloudinary\Test\Integration\IntegrationTestCase;
use Cloudinary\Test\Unit\Asset\AssetTestCase;
use Cloudinary\Test\Unit\UnitTestCase;

/**
* Class AnalysisTest
*/
final class AnalysisTest extends UnitTestCase
{
use RequestAssertionsTrait;

/**
* Test analyze.
*/
public function testAnalyze()
{
$mockAdminApi = new MockAdminApi();
$mockAdminApi->analyze("uri", "captioning", "https://res.cloudinary.com/demo/image/upload/dog");

$lastRequest = $mockAdminApi->getV2MockHandler()->getLastRequest();
$apiV2Configuration = new Configuration();
$apiV2Configuration->api->apiVersion = '2';

self::assertRequestUrl($lastRequest, '/analysis/analyze', "", $apiV2Configuration);
self::assertRequestJsonBodySubset(
$lastRequest,
[
"input_type"=> "uri",
"analysis_type"=> "captioning",
"uri"=> "https://res.cloudinary.com/demo/image/upload/dog",
]
);
}
}
Loading