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

Upgrade Cloudinary PHP API from v1 to v2 #109

Merged
merged 12 commits into from
Nov 28, 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
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.remote_resource:
class: Netgen\RemoteMedia\Core\Provider\Cloudinary\Factory\RemoteResource
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
Loading