Symfony bundle for the Cloudinary PHP SDK.
Require using composer:
$ composer require speicher210/cloudinary-bundleSymfony Flex registers the bundle. Without Flex, add it to config/bundles.php:
return [
// ...
Speicher210\CloudinaryBundle\Speicher210CloudinaryBundle::class => ['all' => true],
// ...
];Configure the cloud and the credentials with the CLOUDINARY_URL from the Cloudinary console, in the form cloudinary://api_key:api_secret@cloud_name:
# config/packages/speicher210_cloudinary.yaml
speicher210_cloudinary:
url: '%env(CLOUDINARY_URL)%'Or set them one by one. Values from the URL take precedence:
speicher210_cloudinary:
cloud_name: my-cloud
access_identifier:
api_key: my-key
api_secret: my-secret
secure: true # HTTPS URLs, the default
analytics: false # Cloudinary's usage statistics in URLs (?_a=…), off by default| Service id | Class | Autowired by |
|---|---|---|
speicher210_cloudinary.cloudinary |
Speicher210\CloudinaryBundle\Cloudinary\Cloudinary |
Speicher210\CloudinaryBundle\Cloudinary\Cloudinary, Cloudinary\Cloudinary |
speicher210_cloudinary.admin |
Speicher210\CloudinaryBundle\Cloudinary\Admin |
Speicher210\CloudinaryBundle\Cloudinary\Admin |
speicher210_cloudinary.uploader |
Speicher210\CloudinaryBundle\Cloudinary\Uploader |
Speicher210\CloudinaryBundle\Cloudinary\Uploader |
The classes extend the SDK's Cloudinary\Cloudinary, Cloudinary\Api\Admin\AdminApi and
Cloudinary\Api\Upload\UploadApi, configured by the bundle:
use Speicher210\CloudinaryBundle\Cloudinary\Uploader;
final readonly class AvatarStorage
{
public function __construct(private Uploader $uploader)
{
}
public function store(string $file, string $userId): string
{
return $this->uploader->upload($file, ['public_id' => 'avatars/' . $userId])['secure_url'];
}
}With TwigBundle enabled, the bundle adds Twig functions, also available as filters, for the URL of an image and for
image, picture and video tags. Their options are
transformation parameters. The tags take HTML
attributes as a third argument; for the picture tag they go on its <img>:
{{ cloudinary_url('sample', {'width': 100, 'height': 100, 'crop': 'fill'}) }}
{# https://res.cloudinary.com/my-cloud/image/upload/c_fill,h_100,w_100/sample #}
{{ 'sample'|cloudinary_image_tag({'width': 100, 'crop': 'scale'}, {'alt': 'A sample', 'loading': 'lazy'}) }}
{# <img alt="A sample" loading="lazy" src="https://res.cloudinary.com/my-cloud/image/upload/c_scale,w_100/sample"> #}
{{ cloudinary_picture_tag('sample', {'width': 100, 'crop': 'scale'}, {'alt': 'A sample'}) }}
{{ cloudinary_video_tag('dog', {'width': 300, 'crop': 'scale'}, {'controls': true}) }}# Upload the files of a directory, subdirectories included. The public ID of a file is the prefix followed by its
# name without the extension; an existing asset with the same public ID is overwritten.
$ bin/console sp210:cloudinary:upload path/to/images --prefix=products/ --filter='*.jpg'
# Show the properties of an asset, with -v also its derived resources.
$ bin/console sp210:cloudinary:info products/shoe -v
# Delete the assets with a public ID prefix, or one asset. Asks for confirmation first.
$ bin/console sp210:cloudinary:delete --prefix=products/
$ bin/console sp210:cloudinary:delete --resource=products/shoeThe tools are run through just (just --list shows every recipe):
$ just check # coding standard, static analysis, composer audit and tests
$ just test # tests
$ just update-snapshots # regenerate the expected output of the console commandsThis package is released under the MIT license.