Skip to content

Commit

Permalink
Merge pull request #109 from netgen/upgrade-cloudinary-php-api
Browse files Browse the repository at this point in the history
Upgrade Cloudinary PHP API from v1 to v2
  • Loading branch information
RandyCupic authored Nov 28, 2024
2 parents d32e40c + 430d525 commit d2b6144
Show file tree
Hide file tree
Showing 23 changed files with 331 additions and 343 deletions.
2 changes: 1 addition & 1 deletion bundle/Command/ShowApiUsageCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$output->writeln($this->getPrettyKey($key) . ': <comment>' . $value . '</comment>');
}

return 0;
return Command::SUCCESS;
}

private function getPrettyKey(string $key): string
Expand Down
12 changes: 6 additions & 6 deletions bundle/Controller/Callback/Cloudinary/Notify.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace Netgen\Bundle\RemoteMediaBundle\Controller\Callback\Cloudinary;

use Cloudinary\Api\NotFound;
use Cloudinary\Uploader;
use Cloudinary\Api\Exception\NotFound as CloudinaryNotFound;
use Cloudinary\Api\Upload\UploadApi;
use Doctrine\ORM\EntityManagerInterface;
use Netgen\RemoteMedia\API\ProviderInterface;
use Netgen\RemoteMedia\API\Values\RemoteResource;
Expand Down Expand Up @@ -197,14 +197,14 @@ private function handleResourceRenamed(array $requestContent): void
/** @var RemoteResource $resource */
foreach ($result as $resource) {
try {
$apiResource = Uploader::explicit(
$apiResource = (new UploadApi())->explicit(
$requestContent['to_public_id'],
[
'type' => CloudinaryRemoteId::fromRemoteId($resource->getRemoteId())->getType(),
'resource_type' => CloudinaryRemoteId::fromRemoteId($resource->getRemoteId())->getResourceType(),
],
);
} catch (NotFound $e) {
} catch (CloudinaryNotFound $e) {
continue;
}

Expand Down Expand Up @@ -293,7 +293,7 @@ private function handleContextChanged(array $requestContent): void
$filenameFromUrl = basename((string) $publicId);

try {
$apiResource = Uploader::explicit(
$apiResource = (new UploadApi())->explicit(
CloudinaryRemoteId::fromRemoteId($resource->getRemoteId())->getResourceId(),
[
'type' => CloudinaryRemoteId::fromRemoteId($resource->getRemoteId())->getType(),
Expand All @@ -302,7 +302,7 @@ private function handleContextChanged(array $requestContent): void
);

basename($apiResource['secure_url']);
} catch (NotFound $e) {
} catch (CloudinaryNotFound $e) {
continue;
}

Expand Down
12 changes: 6 additions & 6 deletions bundle/Resources/config/services/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ services:
class: Netgen\RemoteMedia\Core\Provider\Cloudinary\Gateway\CloudinaryApiGateway
public: false
arguments:
- '@netgen_remote_media.provider.cloudinary.cloudinary_instance'
- '@netgen_remote_media.provider.cloudinary.cloudinary_configuration'
- '@netgen_remote_media.provider.cloudinary.factory.remote_resource'
- '@netgen_remote_media.provider.cloudinary.factory.search_result'
- '@netgen_remote_media.provider.cloudinary.resolver.search_expression'
Expand Down Expand Up @@ -58,8 +58,8 @@ services:
class: Netgen\RemoteMedia\Core\Provider\Cloudinary\Converter\VisibilityType
public: false

netgen_remote_media.provider.cloudinary.factory.cloudinary_instance:
class: Netgen\RemoteMedia\Core\Provider\Cloudinary\Factory\CloudinaryInstance
netgen_remote_media.provider.cloudinary.factory.cloudinary_configuration:
class: Netgen\RemoteMedia\Core\Provider\Cloudinary\Factory\CloudinaryConfiguration
public: false
arguments:
- '%netgen_remote_media.parameters.cloudinary.account_name%'
Expand All @@ -68,9 +68,9 @@ services:
- "%netgen_remote_media.parameters.cloudinary.upload_prefix%"
- "%netgen_remote_media.parameters.use_subdomains%"

netgen_remote_media.provider.cloudinary.cloudinary_instance:
class: Cloudinary
factory: ['@netgen_remote_media.provider.cloudinary.factory.cloudinary_instance', 'create']
netgen_remote_media.provider.cloudinary.cloudinary_configuration:
class: Configuration
factory: ['@netgen_remote_media.provider.cloudinary.factory.cloudinary_configuration', 'create']

netgen_remote_media.provider.cloudinary.factory.md5_file_hash:
class: Netgen\RemoteMedia\Core\Provider\Cloudinary\Factory\Md5FileHash
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
],
"require": {
"php": "^8.1",
"cloudinary/cloudinary_php": "^1.20",
"cloudinary/cloudinary_php": "^2.1",
"symfony/mime": "^5.4 || ^6.2",
"symfony/twig-bundle": "^5.4 || ^6.2",
"symfony/framework-bundle": "^5.4 || ^6.2",
Expand Down
9 changes: 5 additions & 4 deletions docs/UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ Netgen Remote Media Bundle upgrade instructions
Upgrade from 2.0 to 3.0
-----------------------

Version 3.0 is a major release where the whole bundle has been decoupled from eZ and now contains only core features and doesn't depend on eZ anymore. In order to retain all the eZ functionalities (field type, NG admin UI and eZ admin UI), you have to install the new bundle which serves as a connector between Remote Media and eZ (currently WIP).
Version 3.0 is a major release where the whole bundle has been decoupled from eZ and now contains only core features and doesn't depend on eZ anymore. In order to retain all the eZ functionalities (field type, NG admin UI and eZ admin UI), you have to install the [Netgen Remote Media & Ibexa CMS integration](https://github.com/netgen/remote-media-ibexa) bundle which serves as a connector between Remote Media and eZ.

Also, there were a lot of changes during the decoupling from eZ to make things cleaner so there is a lot of breaking changes.

* This bundle doesn't depend on eZ anymore and does not contain any eZ related integration
* This bundle doesn't depend on Netgen Open Graph bundle anymore and does not contain any related integration
* Minimum supported version of PHP is now PHP 7.4
* Minimum supported version of PHP is now PHP 8.1
* This bundle now uses Cloudinary PHP SDK v2 instead of v1
* Most of the classes in the codebase are now `final` - if you have any overrides in your project, refactor them to use the Decorator pattern instead
* The main value object `Netgen\Bundle\RemoteMediaBundle\Core\FieldType\RemoteMedia\Value` which was extending eZ field type value has now been renamed to `Netgen\RemoteMedia\API\Values\RemoteResource` and all methods use or return this new one; methods and properties remained the same; now it's a standalone value object
* The variation object `Netgen\Bundle\RemoteMediaBundle\Core\FieldType\RemoteMedia\Variation` has been renamed to `Netgen\RemoteMedia\API\Values\Variation` and all methods use or return this new one; methods and properties remained the same
Expand All @@ -34,7 +35,7 @@ Also, there were a lot of changes during the decoupling from eZ to make things c
* `public static function createFromParameters(array $parameters): self`
* `public static function createFromCloudinaryResponse(array $response): self`
* The bundle was using eZ's `ezpublish.cache_pool` cache pool for caching while it was depending on eZ. Now it requires cache pool to be provided in order to work. See [Install instructions](INSTALL.md) for more info.
* Paramter for cache TTL `netgen_remote_media.cloudinary.cache_ttl` has been removed in favour of semantic configuration for cache. See [Install instructions](INSTALL.md) for more info.
* Parameter for cache TTL `netgen_remote_media.cloudinary.cache_ttl` has been removed in favour of semantic configuration for cache. See [Install instructions](INSTALL.md) for more info.

### Code changes

Expand All @@ -46,7 +47,7 @@ Old object `Netgen\Bundle\RemoteMediaBundle\Core\FieldType\RemoteMedia` has been
* all properties are now private and there are corresponding getters as well as some helper methods to manipulate with the object
* static constructors have been removed from the value object -> they've been replaced with factory
* now it contains `id` which represents the ID of the stored resource in the database (via Doctrine) -> can be `null` if the resource has been fetched from remote
* now it contains `remoteId` which is used to uniquely identify the resource on the cloud -> in case when cloud providers require multiple parameters to uniquely identify the resource (eg. Cloudinary requires `resourceId`, `resourceType` and `type`), each provider is responsible to merge this info into single array which will be used as `remoteId`
* now it contains `remoteId` which is used to uniquely identify the resource on the cloud -> in case when cloud providers require multiple parameters to uniquely identify the resource (eg. Cloudinary requires `resourceId`, `resourceType` and `type`), each provider is responsible to merge this info into single string which will be used as `remoteId`
* `mediaType` property has been removed; now we have a single `type` and it's up to the provider to convert this to the appropriate type for cloud provider
* now it contains two new types: `audio` and `document`
* now it contains only single `url` property instead of both URL and secure URL - it's up to provider to decide whether it will provide secure or not secure URLs
Expand Down
9 changes: 7 additions & 2 deletions lib/Core/Provider/Cloudinary/CloudinaryProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Netgen\RemoteMedia\Core\Provider\Cloudinary;

use Cloudinary\Configuration\TagConfig;
use Doctrine\ORM\EntityManagerInterface;
use Netgen\RemoteMedia\API\Factory\DateTime as DateTimeFactoryInterface;
use Netgen\RemoteMedia\API\Search\Query;
Expand All @@ -28,7 +29,6 @@
use function array_merge;
use function basename;
use function count;
use function default_poster_options;
use function preg_match;
use function sprintf;
use function str_replace;
Expand Down Expand Up @@ -280,7 +280,12 @@ protected function internalBuildVideoThumbnail(RemoteResource $resource, array $
$resource instanceof AuthenticatedRemoteResource ? $resource->getToken() : null,
);

return new RemoteResourceVariation($resource, $thumbnailUrl, array_merge(default_poster_options(), $options));
$defaultPosterOptions = [
'format' => TagConfig::VIDEO_POSTER_FORMAT,
'resource_type' => 'video',
];

return new RemoteResourceVariation($resource, $thumbnailUrl, array_merge($defaultPosterOptions, $options));
}

protected function generatePictureTag(RemoteResource $resource, array $transformations = [], array $htmlAttributes = []): string
Expand Down
4 changes: 2 additions & 2 deletions lib/Core/Provider/Cloudinary/Converter/VisibilityType.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ public function toCloudinaryAccessControl(string $visibility): array
switch ($visibility) {
case RemoteResource::VISIBILITY_PROTECTED:
return [
'access_type' => 'token',
['access_type' => 'token'],
];

case RemoteResource::VISIBILITY_PUBLIC:
default:
return [
'access_type' => 'anonymous',
['access_type' => 'anonymous'],
];
}
}
Expand Down
30 changes: 30 additions & 0 deletions lib/Core/Provider/Cloudinary/Factory/CloudinaryConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Netgen\RemoteMedia\Core\Provider\Cloudinary\Factory;

use Cloudinary\Configuration\Configuration;

final class CloudinaryConfiguration
{
public function __construct(
private string $cloudName,
private string $apiKey,
private string $apiSecret,
private string $uploadPrefix,
private bool $useSubdomains = false,
) {}

public function create(): Configuration
{
return Configuration::instance([
'cloud_name' => $this->cloudName,
'api_key' => $this->apiKey,
'api_secret' => $this->apiSecret,
'upload_prefix' => $this->uploadPrefix,
'cdn_subdomain' => $this->useSubdomains,
'force_version' => false,
]);
}
}
39 changes: 0 additions & 39 deletions lib/Core/Provider/Cloudinary/Factory/CloudinaryInstance.php

This file was deleted.

4 changes: 2 additions & 2 deletions lib/Core/Provider/Cloudinary/Factory/RemoteResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Netgen\RemoteMedia\Core\Provider\Cloudinary\Factory;

use Cloudinary\Asset\Media;
use Netgen\RemoteMedia\API\Factory\FileHash as FileHashFactoryInterface;
use Netgen\RemoteMedia\API\Factory\RemoteResource as RemoteResourceFactoryInterface;
use Netgen\RemoteMedia\API\Values\RemoteResource as RemoteResourceValue;
Expand All @@ -13,7 +14,6 @@
use Netgen\RemoteMedia\Exception\Factory\InvalidDataException;

use function basename;
use function cloudinary_url_internal;
use function in_array;
use function is_array;
use function pathinfo;
Expand Down Expand Up @@ -79,7 +79,7 @@ private function resolveCorrectUrl(array $data): string
'secure' => true,
];

return cloudinary_url_internal($data['public_id'], $options);
return (string) Media::fromParams($data['public_id'], $options)->toUrl();
}

private function resolveResourceType(array $data): string
Expand Down
Loading

0 comments on commit d2b6144

Please sign in to comment.