Installation:
composer require clarity-project/cdn-bundle
Add to config/bundles.php:
return [
// ...
ClarityProject\CdnBundle\ClarityCdnBundle::class => ['all' => true],
];
Configuration:
Update config/packages/clarity_cdn.yaml (create if missing):
clarity_cdn:
default_cdn: 'local' # or 'remote'
cdn:
local:
type: 'local'
path: '%kernel.project_dir%/public/uploads'
remote:
type: 's3' # or 'ftp', 'rackspace', etc.
options: { /* provider-specific config */ }
First Use Case:
use ClarityProject\CdnBundle\Manager\CdnManager;
$cdnManager = $this->container->get('clarity_cdn.manager');
$filePath = $cdnManager->upload('local', $file, 'user_avatars');
$url = $cdnManager->getUrl('local', $filePath);
config/packages/clarity_cdn.yaml: Default configuration.src/Manager/CdnManager.php: Core logic for uploads/URLs.Resources/doc/index.md: Official documentation (if available).user_avatars/123.jpg) in the database, not full URLs.
$abstractPath = $cdnManager->upload('remote', $file, 'user_avatars');
// Save `$abstractPath` to DB, not the full URL.
// Switch to 'remote' CDN in config, no code changes needed.
$url = $cdnManager->getUrl($cdnName, $abstractPath);
// Use `$url` in templates/views.
<img src="{{ clarity_cdn_url('local', entity.imagePath) }}">
Add to twig.config.yaml:
twig:
globals:
clarity_cdn_url: '@clarity_cdn.twig.url_generator'
$cdnManager->delete('local', $abstractPath);
foreach ($files as $file) {
$cdnManager->upload('remote', $file, 'batch_uploads');
}
Service Provider Binding:
Bind the CDN manager in AppServiceProvider:
public function register()
{
$this->app->bind('clarity_cdn.manager', function ($app) {
return new \ClarityProject\CdnBundle\Manager\CdnManager(
$app['clarity_cdn.config'],
$app['filesystem']
);
});
}
Filesystem Integration: Use Laravel’s filesystem to handle local uploads:
# config/filesystems.php
'disks' => [
'cdn_local' => [
'driver' => 'local',
'root' => storage_path('app/cdn'),
],
],
Update clarity_cdn.yaml:
clarity_cdn:
cdn:
local:
type: 'local'
filesystem: 'cdn_local' # Use Laravel's filesystem
Artisan Commands: Extend the bundle with custom commands for maintenance:
namespace App\Console\Commands;
use ClarityProject\CdnBundle\Manager\CdnManager;
use Illuminate\Console\Command;
class SyncCdnFiles extends Command
{
protected $cdnManager;
public function __construct(CdnManager $cdnManager)
{
parent::__construct();
$this->cdnManager = $cdnManager;
}
public function handle()
{
// Sync logic here
}
}
Event Listeners: Trigger actions on upload/deletion (e.g., thumbnail generation):
// config/packages/clarity_cdn.yaml
clarity_cdn:
events:
upload: ['App\Events\HandleUploadedFile']
delete: ['App\Events\HandleDeletedFile']
Abstract Path Collisions:
profile.jpg) for multiple files.profile_123.jpg or UUIDs).
$abstractPath = 'user_avatars/' . uniqid() . '_' . $file->getClientOriginalName();
CDN Provider Quirks:
PutObject, GetObject, and DeleteObject.path in config is writable (chmod -R 775 public/uploads).Caching Headaches:
$url = $cdnManager->getUrl('remote', $abstractPath) . '?v=' . filemtime($localPath);
Symfony vs. Laravel Mismatches:
ContainerInterface; Laravel uses Illuminate\Container\Container.Deprecated Methods:
// Override CdnManager in a trait or subclass
namespace App\Services;
use ClarityProject\CdnBundle\Manager\CdnManager as BaseCdnManager;
class CdnManager extends BaseCdnManager
{
public function modernUpload($cdnName, $file, $directory)
{
// Custom logic
}
}
Log Uploads/Deletions:
Enable debug mode in clarity_cdn.yaml:
clarity_cdn:
debug: true
Check logs for errors (e.g., permission denied, connection issues).
Verify Abstract Paths: Dump abstract paths to ensure they’re unique and correctly formatted:
dd($cdnManager->upload('local', $file, 'test'));
Test Locally First:
Use the local CDN for development to avoid remote provider costs:
clarity_cdn:
default_cdn: 'local'
Custom CDN Drivers: Extend the bundle by adding new driver classes. Example for a custom driver:
namespace App\Cdn\Driver;
use ClarityProject\CdnBundle\Driver\AbstractDriver;
class CustomDriver extends AbstractDriver
{
public function upload($file, $directory)
{
// Custom upload logic (e.g., to a CDN API)
}
public function getUrl($path)
{
// Custom URL generation
}
}
Register in clarity_cdn.yaml:
clarity_cdn:
cdn:
custom:
type: 'custom'
class: 'App\Cdn\Driver\CustomDriver'
Pre/Post Hooks: Add callbacks for uploads/deletions via events (Symfony-style):
clarity_cdn:
events:
upload:
- ['App\Services\ThumbnailGenerator', 'generate']
- ['App\Services\Logger', 'logUpload']
Middleware for URLs: Proxy CDN URLs through Laravel middleware to add auth or analytics:
Route::get('/cdn/{cdn}/{path}', function ($cdn, $path) {
$cdnManager = app('clarity_cdn.manager');
$url = $cdnManager->getUrl($cdn, $path);
// Add middleware logic (e.g., rate limiting)
return redirect()->to($url);
});
Fallback Mechanisms:
How can I help you explore Laravel packages today?