Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cloudinary Php Laravel Package

cloudinary/cloudinary_php

Official Cloudinary PHP SDK for uploading and managing images/videos, applying transformations, optimizing delivery, and working with URLs and resources. Supports signed requests, authentication, and integration with Cloudinary’s API for media workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require cloudinary/cloudinary_php
    

    Register the service provider in config/app.php (Laravel 5.5+ auto-discovers).

  2. Configuration Add credentials to .env:

    CLOUDINARY_CLOUD_NAME=your_cloud_name
    CLOUDINARY_API_KEY=your_api_key
    CLOUDINARY_API_SECRET=your_api_secret
    

    Publish the config file:

    php artisan vendor:publish --provider="Cloudinary\CloudinaryLaravel\CloudinaryServiceProvider"
    

    Edit config/cloudinary.php for default settings (e.g., folder structure, transformations).

  3. First Use Case Upload an image from a request:

    use Cloudinary\Cloudinary;
    use Cloudinary\Configuration\Configuration;
    
    $cloudinary = new Cloudinary(new Configuration([
        'cloud' => [
            'cloud_name' => env('CLOUDINARY_CLOUD_NAME'),
            'api_key'    => env('CLOUDINARY_API_KEY'),
            'api_secret' => env('CLOUDINARY_API_SECRET'),
        ],
    ]));
    
    $result = $cloudinary->uploadApi()->upload(
        fopen($_FILES['image']['tmp_name'], 'r'),
        ['folder' => 'user_uploads']
    );
    

Implementation Patterns

Common Workflows

1. Uploading Files

  • From Requests
    $result = $cloudinary->uploadApi()->upload(
        fopen($_FILES['file']['tmp_name'], 'r'),
        ['folder' => 'uploads/' . auth()->id()]
    );
    
  • From URLs
    $result = $cloudinary->uploadApi()->upload(
        'https://example.com/image.jpg',
        ['folder' => 'remote_uploads']
    );
    

2. Generating URLs

  • Dynamic Transformations
    $url = $cloudinary->url()->transformation([
        'width' => 500,
        'height' => 300,
        'crop' => 'limit',
        'gravity' => 'face'
    ])->generate('sample.jpg');
    
  • Signed URLs (for private assets)
    $url = $cloudinary->url()->transformation([
        'effect' => 'sepia'
    ])->generate('private.jpg', ['expires' => time() + 3600]);
    

3. Deleting Assets

$cloudinary->deleteResourcesByTag('user_' . auth()->id());
// OR delete by public ID
$cloudinary->deleteResources(['public_id' => 'sample.jpg']);

4. Batch Operations

$publicIds = ['image1.jpg', 'image2.jpg'];
$cloudinary->deleteResources($publicIds);

5. Integration with Laravel Storage

Create a custom Cloudinary adapter for Storage::disk():

// config/filesystems.php
'cloudinary' => [
    'driver' => 'cloudinary',
    'cloudinary' => [
        'cloud_name' => env('CLOUDINARY_CLOUD_NAME'),
        'api_key'    => env('CLOUDINARY_API_KEY'),
        'api_secret' => env('CLOUDINARY_API_SECRET'),
    ],
],

Then use it like any other disk:

Storage::disk('cloudinary')->put('folder/file.jpg', fopen('local.jpg', 'r'));

6. Laravel Eloquent Relationships

Use accessors/mutators in models:

class Product extends Model {
    public function getImageUrlAttribute() {
        return $this->image_id
            ? $this->cloudinary()->url()->generate($this->image_id)
            : null;
    }

    public function setImageUrlAttribute($url) {
        $result = $this->cloudinary()->uploadApi()->upload($url);
        $this->image_id = $result['public_id'];
    }
}

Gotchas and Tips

Pitfalls and Debugging

  1. API Key/Secret Mismatch

    • Symptom: Authentication failed errors.
    • Fix: Double-check .env and ensure no trailing spaces in credentials.
  2. Folder Permissions

    • Symptom: Uploads fail silently or appear in the root folder.
    • Fix: Explicitly set folders in upload options:
      ['folder' => 'user_' . auth()->id() . '/uploads']
      
  3. Transformation Errors

    • Symptom: Invalid transformation or broken images.
    • Fix: Validate transformations using Cloudinary’s transformation reference.
    • Debug: Use the generate() method to test URLs before rendering.
  4. Rate Limiting

    • Symptom: 429 Too Many Requests.
    • Fix: Implement exponential backoff or upgrade your plan.
  5. Private Assets

    • Gotcha: Signed URLs expire. Cache them or regenerate on demand.
    • Tip: Use middleware to validate signed URLs:
      Route::get('/private/{id}', function ($id) {
          $url = $this->cloudinary->url()->generate($id, ['expires' => time() + 300]);
          return redirect()->to($url);
      });
      

Configuration Quirks

  1. Default Folder

    • If not specified, uploads go to the root. Set a default in config/cloudinary.php:
      'default_folder' => 'app_uploads',
      
  2. Transformation Caching

    • Enable caching for performance:
      $url = $cloudinary->url()->transformation([
          'fetch_format' => 'auto',
          'quality' => 'auto'
      ])->generate('image.jpg', ['c_name' => 'my_cache']);
      
  3. Async Uploads

    • For large files, use the upload() method with async:
      $result = $cloudinary->uploadApi()->upload($file, ['async' => true]);
      

Extension Points

  1. Custom Upload Presets

    • Create reusable presets for common transformations:
      $cloudinary->uploadApi()->upload($file, [
          'upload_preset' => 'my_preset_name'
      ]);
      
    • Define presets in Cloudinary’s dashboard under Settings > Upload.
  2. Webhooks

    • Use Cloudinary’s notifications to trigger Laravel events:
      // Example: Listen for upload notifications
      $cloudinary->uploadApi()->upload($file, [
          'notification_url' => route('cloudinary.webhook')
      ]);
      
  3. Middleware for Transformations

    • Create middleware to apply default transformations to all image URLs:
      public function handle($request, Closure $next) {
          $response = $next($request);
          $response->setContent(
              str_replace(
                  'sample.jpg',
                  $this->cloudinary->url()->transformation(['width' => 800])->generate('sample.jpg'),
                  $response->getContent()
              )
          );
          return $response;
      }
      
  4. Fallback for Local Storage

    • Implement a fallback if Cloudinary is down:
      try {
          $url = $cloudinary->url()->generate('image.jpg');
      } catch (\Exception $e) {
          $url = Storage::disk('local')->url('fallback/image.jpg');
      }
      
  5. Testing

    • Use a .env.testing file with a dummy Cloudinary account or mock the client:
      $cloudinary = Mockery::mock(Cloudinary::class);
      $cloudinary->shouldReceive('url')->andReturnSelf();
      $cloudinary->shouldReceive('generate')->andReturn('http://test.url/image.jpg');
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky