bgillieron / yii2-cloudinary
A Yii2-friendly wrapper for Cloudinaryβs PHP SDK: upload widget, responsive images, and media management.
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Type:yii2-extension
Requires
- cloudinary/cloudinary_php: ^2.0
- yiisoft/yii2: ~2.0.0
README
Cloudinary integration for the Yii2 PHP Framework.
This extension provides a Yii2-friendly wrapper around the official Cloudinary PHP SDK, enabling seamless uploads, media management, and responsive image rendering in Yii2 projects.
π Project Structure
yii2-cloudinary/
βββ src/
β βββ assets/
β β βββ photoswipe/
β β β βββ photoswipe-lightbox.esm.min.js
β β β βββ photoswipe.esm.min.js
β β β βββ photoswipe.css
β β βββ PhotoSwipeAsset.php
β βββ components/
β β βββ Yii2CloudinaryComponent.php
β βββ controllers/
β β βββ Yii2CloudinaryController.php
β βββ messages/
β β βββ en/
β β β βββ uploadWidget.php
β β βββ text.json
β βββ migrations/
β β βββ m250430_120000_create_cloudinary_media_tables.php
β βββ models/
β β βββ CloudinaryImageMeta.php
β β βββ CloudinaryMedia.php
β β βββ CloudinaryMediaDesc.php
β β βββ Module.php
βββ cloudinary-media-migrations.md
βββ composer.json
βββ LICENSE
βββ README.md
βββ render-responsive-image.md
βββ upload-widget-localization.md
π Features
- Upload images and files to Cloudinary with a single call
- Automatically configure credentials via Yii component
- Drop-in Upload Widget integration with runtime options
- Responsive image rendering with automatic
srcset
- Orientation-aware rendering via image meta
- PhotoSwipe support for lightbox galleries
- Database schema for multilingual media metadata
- Easily relate uploaded media to your own models
- Fully translatable Upload Widget UI
π¦ Installation
Install the extension via Composer:
composer require bgillieron/yii2-cloudinary
π§ Configuration
Add the module and component to your Yii2 config:
'modules' => [ 'cloudinary' => [ 'class' => 'yii2cloudinary\Module', ], ], 'components' => [ 'yii2cloudinary' => [ 'class' => \yii2cloudinary\components\Yii2CloudinaryComponent::class, 'cloudName' => $_ENV['CLOUDINARY_CLOUD_NAME'], 'apiKey' => $_ENV['CLOUDINARY_API_KEY'], 'apiSecret' => $_ENV['CLOUDINARY_API_SECRET'], 'uploadPreset' => $_ENV['CLOUDINARY_UPLOAD_PRESET'], 'uploadHandlerUrl' => '/cloudinary/yii2-cloudinary/upload-handler', 'db_defaultPublished' => false, 'db_defaultOrder' => 500, 'relationSaverMap' => [ 'test-widget' => function ($media) { Yii::$app->db->createCommand()->insert('test_media_relation', [ 'media_id' => $media->id, 'label' => 'Uploaded from test widget', ])->execute(); }, ], ], ],
π§± Migrations
To create the necessary tables for storing Cloudinary media and metadata, run:
php yii migrate --migrationPath=@yii2cloudinary/migrations
This will create:
cloudinary_media
cloudinary_media_desc
cloudinary_image_meta
π For full details on table structure and purpose, see Cloudinary Media Migrations.
π Media Usage
Uploading Files (Server-Side)
Yii::$app->yii2cloudinary->upload('/path/to/image.jpg', [ 'folder' => 'my-uploads', 'tags' => ['profile', 'gallery'], 'relationKey' => 'post-image', ]);
This method:
- Uploads the file to Cloudinary
- Saves the
cloudinary_media
record - If
relationKey
is provided and defined in your config, invokes the matching relation handler
π Saving Upload Result & Creating Relations
When a file is uploaded to Cloudinary, the extension automatically saves a corresponding record in the database (cloudinary_media
) β but in most real-world projects, youβll also want to associate that file with a specific model (like Post
, Product
, User
, etc.).
To keep your application logic clean and flexible, this extension introduces the concept of relation callbacks, defined via the relationSaverMap
.
π§ Why Use relationSaverMap
?
- You may need different logic for different upload contexts (e.g. a product image, an avatar, a gallery).
- Each upload (or widget instance) can pass a
relationKey
to identify which logic should run. - You configure these mappings once in your app config β no need to pass closures at runtime.
ποΈ Define Any Number of Relation Handlers
'relationSaverMap' => [ 'product-gallery' => function ($media) { Yii::$app->db->createCommand()->insert('product_media', [ 'media_id' => $media->id, 'product_id' => 123, 'position' => 1, ])->execute(); }, 'user-avatar' => fn($media) => Yii::$app->user->identity->link('avatar', $media), 'post-image' => fn($media) => Post::findOne(5)->link('media', $media), ],
Each callable will be invoked automatically after a successful upload, only if the relationKey
matches.
Rendering a Responsive Image
echo Yii::$app->yii2cloudinary->renderResponsiveImage($media, [400, 800], [ 'class' => 'img-fluid', ]);
- Generates
<img>
tag with optimized Cloudinarysrcset
- Optional aspect ratio detection (e.g.
'4:3'
,'1:1'
) - Orientation-aware layout using image meta (landscape vs portrait)
- Lazy loading and format auto-selection supported
π See Render Responsive Image for advanced usage and options.
πΌ Upload Widget & UI
Rendering the Upload Widget
Yii::$app->yii2cloudinary->uploadWidget('upload_widget', [ 'relationKey' => 'test-widget', // π this triggers your configured relationSaverMap callback ]);
This registers the Cloudinary Upload Widget and binds it to the DOM element with the given ID.
Key behaviors:
- Automatically registers and loads Cloudinaryβs JavaScript dependencies
- Uploads files to Cloudinary and sends metadata to your configured
uploadHandlerUrl
endpoint, which persists the media and optionally links it using yourrelationSaverMap
- If a
relationKey
is passed, it is forwarded to the server to trigger a matching callback from yourrelationSaverMap
- You can also pass
text
overrides for localization
π To attach uploaded media to a model, define your relation logic in relationSaverMap
, and refer to it using relationKey
.
π Upload Handler URL
When a file is uploaded via the widget, Cloudinary sends the file to their CDN,
then triggers a callback with metadata that is posted to your appβs upload handler.
By default, this handler is set to:
'uploadHandlerUrl' => '/yii2cloudinary/upload-handler',
You can override this in your component config if needed:
'uploadHandlerUrl' => '/custom/path/to/upload-handler',
This endpoint must match the route defined by your Yii2CloudinaryController::actionUploadHandler()
and is responsible for saving the uploaded media record and executing your relationSaverMap
logic.
Only change this if absolutely necessary β overriding it incorrectly will break key functionality of this module.
π Upload Widget Localization
This extension supports:
- Default English UI via embedded translations
- App-level language overrides via
messages/<lang>/uploadWidget.php
- Runtime
text
overrides passed touploadWidget()
π See Upload Widget Localization for a complete guide.
πΌ Lightbox Support (PhotoSwipe)
Register the ESM Asset Bundle
use yii2cloudinary\assets\PhotoSwipeAsset; PhotoSwipeAsset::register($this);
Initialize in View
<?php $baseUrl = $this->assetManager->getBundle(\yii2cloudinary\assets\PhotoSwipeAsset::class)->baseUrl; ?> <script type="module"> import PhotoSwipeLightbox from '<?= $baseUrl ?>/photoswipe-lightbox.esm.min.js'; import PhotoSwipe from '<?= $baseUrl ?>/photoswipe.esm.min.js'; const lightbox = new PhotoSwipeLightbox({ gallery: '.my-gallery', children: 'a', pswpModule: PhotoSwipe, padding: 20, showHideAnimationType: 'zoom', }); lightbox.init(); </script>
π ES modules require explicit import
and do not auto-run.
βοΈ Advanced Access
SDK Access
$cloudinary = Yii::$app->yii2cloudinary->getCloudinary(); $url = $cloudinary->image('your-public-id')->toUrl();
This returns the Cloudinary\Cloudinary
instance for advanced transformations.
Model Reference
These models support multilingual metadata and responsive rendering:
π License
MIT License
Β© Brendon GilliΓ©ron