Skip to content

Repository files navigation

Cloudinary Bundle

Build Software License

Symfony bundle for the Cloudinary PHP SDK.

Installation

Require using composer:

$ composer require speicher210/cloudinary-bundle

Symfony Flex registers the bundle. Without Flex, add it to config/bundles.php:

return [
    // ...
    Speicher210\CloudinaryBundle\Speicher210CloudinaryBundle::class => ['all' => true],
    // ...
];

Configuration

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

Usage

Services

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'];
    }
}

Twig

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}) }}

Console commands

# 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/shoe

Development

The 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 commands

License

This package is released under the MIT license.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages