PHPackages                             snowsoft/cdn-laravel-adapter - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. snowsoft/cdn-laravel-adapter

ActiveLibrary[File &amp; Storage](/categories/file-storage)

snowsoft/cdn-laravel-adapter
============================

Laravel Storage adapter for CDN Services Node.js backend

v0.06(2mo ago)036↑100%MITPHP

Since Feb 12Pushed 2mo agoCompare

[ Source](https://github.com/snowsoft/cdn-laravel-adapter)[ Packagist](https://packagist.org/packages/snowsoft/cdn-laravel-adapter)[ Docs](https://github.com/snowsoft/cdn-laravel-adapter)[ RSS](/packages/snowsoft-cdn-laravel-adapter/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (6)Dependencies (6)Versions (7)Used By (0)

CDN Services Laravel Adapter
============================

[](#cdn-services-laravel-adapter)

[![Latest Version on Packagist](https://camo.githubusercontent.com/b9b0d1da5b2012e10f94b9e59bd1d70a839d0c930b0fa5bc5744f44c3a6921bb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736e6f77736f66742f63646e2d6c61726176656c2d616461707465722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/snowsoft/cdn-laravel-adapter)[![Total Downloads](https://camo.githubusercontent.com/90fe36e51621a692cc7a0d6b8bcf4b41026396fc0a957f870afefac109648672/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f736e6f77736f66742f63646e2d6c61726176656c2d616461707465722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/snowsoft/cdn-laravel-adapter)[![PHP from Packagist](https://camo.githubusercontent.com/9bd4056135c2d13db1b9d1f92a36827921a747f649512d931c0002e34a5ae665/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f736e6f77736f66742f63646e2d6c61726176656c2d616461707465723f7374796c653d666c61742d737175617265)](https://packagist.org/packages/snowsoft/cdn-laravel-adapter)

Laravel Storage adapter for CDN Services Node.js backend. Use CDN Services as a Laravel filesystem disk (Laravel 9, 10, 11, 12). **Domain Driven Design (DDD)** uyumlu yapı: Domain (value objects, port interfaces), Application (use case services), Infrastructure (HTTP gateway).

- **Packagist:** [packagist.org/packages/snowsoft/cdn-laravel-adapter](https://packagist.org/packages/snowsoft/cdn-laravel-adapter)
- **Source:** [github.com/snowsoft/cdn-laravel-adapter](https://github.com/snowsoft/cdn-laravel-adapter)

### Özellikler

[](#özellikler)

ÖzellikAçıklama**Storage disk**`Storage::disk('cdn-services')` ile put/get/delete/url, caption, tags, folder, visibility**CdnServicesAuth**Kayıt (registration token), giriş, `tokenForUser` ile JWT**Depolama kotası**`QuotaExceededException`, `getQuotaRemaining()`, `usage()` ile quotaBytes/quotaMB**CdnServicesPdf**PDF yükleme, **HTML'den PDF oluşturma** (`generateFromHtml`), session ile süreli erişim, DDD (PdfDocument, PdfSession)**CdnServicesApi**Meta, list, usage, import, placeholder, signed URL, `processedUrl`, **Cloudflare** `cloudflareProcessedUrl`**CdnApi / CdnBulk**Toplu işlem: `CdnApi::upload`, `importBatch`, `bulkDelete`; `CdnBulk::uploadMany`; Artisan: `cdn:bulk-upload`, `cdn:import-urls`, `cdn:bulk-delete`**CdnMinify**JS/CSS sıkıştırma (minify), **publish** (ledger + kalıcı asset), ledger doğrulama; DDD (MinifyPublishResult, LedgerVerification).---

DDD yapısı
----------

[](#ddd-yapısı)

KatmanAçıklama**Domain**`Domain\Pdf\PdfDocument`, `PdfSession` (value objects); `PdfStorageGatewayInterface` (port). **Minify:** `Domain\Minify\MinifyPublishResult`, `LedgerVerification`; `MinifyGatewayInterface` (port).**Application**`Application\Pdf\PdfStorageService` – PDF use case'leri. **Minify:** `Application\Minify\MinifyService` – minifyJs, minifyCss, publishJs, publishCss, assetUrl, verifyLedger.**Infrastructure**`Infrastructure\Http\PdfStorageGateway` – backend `/api/pdf/*`. **Minify:** `Infrastructure\Http\MinifyGateway` – backend `/api/minify/*`.**Bulk (Contracts/Services)**`Contracts\CdnApiClientInterface`, `CdnBulkUploadServiceInterface`; `Services\CdnApiClient`, `CdnBulkUploadService`; DTOs: `BulkUploadResult`, `BatchImportResult`, `BulkDeleteResult`.Bağımlılık Domain → Application → Infrastructure yönünde; uygulama `PdfStorageGatewayInterface` / `MinifyGatewayInterface` ile tip bağımlılığı kurar, implementasyon ServiceProvider'da bağlanır.

### Minify (DDD)

[](#minify-ddd)

Backend’de Minify servisi açıksa (`MINIFY_SERVICE_URL`), **CdnMinify** facade ile JS/CSS sıkıştırma, yayınlama (ledger + asset) ve ledger doğrulama kullanılır:

```
use CdnServices\Facades\CdnMinify;
use CdnServices\Domain\Minify\MinifyPublishResult;

// Sadece sıkıştır (kaydetmez)
$minifiedJs = CdnMinify::minifyJs($rawJs);
$minifiedCss = CdnMinify::minifyCss($rawCss);

// Yayınla: sıkıştır + ledger'a yaz + kalıcı asset URL
$result = CdnMinify::publishJs($rawJs);  // MinifyPublishResult: assetId, url, kind, size
$result = CdnMinify::publishCss($rawCss);

// Asset erişim URL'i (script/link ile kullanılır)
$url = CdnMinify::assetUrl($result->assetId);

// Ledger zincir doğrulama
$verification = CdnMinify::verifyLedger();  // LedgerVerification: valid, message, entries

if (CdnMinify::isAvailable()) {
    // Minify servisi kullanılabilir
}
```

---

Toplu işlem (DDD: CdnApi, CdnBulk, Artisan)
-------------------------------------------

[](#toplu-işlem-ddd-cdnapi-cdnbulk-artisan)

**Servisler:** `CdnApiClientInterface` (upload, importBatch, bulkDelete), `CdnBulkUploadServiceInterface` (uploadMany). **Facades:** `CdnApi`, `CdnBulk` (alias'ları eklemek için `config/app.php` veya composer `extra.laravel.aliases` içine `CdnApi` → `CdnServices\Facades\CdnApi`, `CdnBulk` → `CdnServices\Facades\CdnBulk` ekleyin).

**Artisan komutları:**

```
# Toplu dosya yükleme (dizin veya tek dosya)
php artisan cdn:bulk-upload /path/to/products --bucket=local --folder=ürünler --tags=ürün,yeni

# URL listesinden import (--file= veya argüman)
php artisan cdn:import-urls --file=urls.txt --bucket=local

# Toplu silme
php artisan cdn:bulk-delete --file=ids.txt
```

**Kod örneği:**

```
use CdnServices\Contracts\CdnBulkUploadServiceInterface;
use CdnServices\Facades\CdnApi;
use CdnServices\DTOs\BatchImportResult;
use CdnServices\DTOs\BulkDeleteResult;

// Toplu yükleme (controller'da inject)
$result = app(CdnBulkUploadServiceInterface::class)->uploadMany(
    ['/path/to/1.jpg', '/path/to/2.png'],
    ['bucket' => 'local', 'folder' => 'ürünler']
);
$result->uploadedIds();

// URL import
$res = CdnApi::importBatch(['https://example.com/1.jpg'], ['bucket' => 'local']);
$result = BatchImportResult::fromApiResponse($res);

// Toplu silme
$res = CdnApi::bulkDelete(['id1', 'id2']);
$result = BulkDeleteResult::fromApiResponse($res);
```

---

Requirements
------------

[](#requirements)

- PHP 8.0+
- Laravel 9.x, 10.x, 11.x or 12.x
- [CDN Services](https://github.com/snowsoft/cdn-services) Node.js backend

---

Installation
------------

[](#installation)

Install via Composer (Packagist):

```
composer require snowsoft/cdn-laravel-adapter
```

Service provider and aliases are auto-discovered. Publish config:

```
php artisan vendor:publish --tag=cdn-services-config
```

### Install from GitHub (development)

[](#install-from-github-development)

Add the VCS repository to `composer.json`, then require the package:

```
{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/snowsoft/cdn-laravel-adapter"
        }
    ]
}
```

```
composer require snowsoft/cdn-laravel-adapter
```

### Manual install

[](#manual-install)

1. Clone the repo into your project (e.g. `packages/cdn-laravel-adapter`).
2. Add PSR-4 autoload: `"CdnServices\\": "packages/cdn-laravel-adapter/src/"`.
3. Register `CdnServices\CdnServicesServiceProvider` in `config/app.php` or `bootstrap/providers.php`.
4. Run `php artisan vendor:publish --tag=cdn-services-config`.

---

Configuration
-------------

[](#configuration)

### Environment (`.env`)

[](#environment-env)

```
CDN_SERVICES_BASE_URL=http://localhost:3012
CDN_SERVICES_TOKEN=your-jwt-token-here
# Backend'de REGISTRATION_TOKEN zorunluysa; kayıt için (CdnServicesAuth::register)
CDN_SERVICES_REGISTRATION_TOKEN=
CDN_SERVICES_DISK=local
CDN_SERVICES_DEFAULT_DISK=local
CDN_SERVICES_TIMEOUT=30
```

### Filesystem (`config/filesystems.php`)

[](#filesystem-configfilesystemsphp)

```
'disks' => [
    // ...
    'cdn-services' => [
        'driver' => 'cdn-services',
        'base_url' => env('CDN_SERVICES_BASE_URL', 'http://localhost:3012'),
        'token' => env('CDN_SERVICES_TOKEN'),
        'disk' => env('CDN_SERVICES_DISK', 'local'),
    ],
],
```

---

Usage
-----

[](#usage)

### Storage facade

[](#storage-facade)

```
use Illuminate\Support\Facades\Storage;

// Upload (optional: caption, tags, folder, visibility)
Storage::disk('cdn-services')->put('images/photo.jpg', $fileContents, [
    'caption' => 'Açıklama',
    'tags' => ['ürün', 'kampanya'],
    'folder' => 'galeri',
    'visibility' => 'public', // public|private|unlisted
]);

// Read, exists, delete, url, copy, move
$contents = Storage::disk('cdn-services')->get('images/photo.jpg');
$exists = Storage::disk('cdn-services')->exists('images/photo.jpg');
Storage::disk('cdn-services')->delete('images/photo.jpg');
$url = Storage::disk('cdn-services')->url('images/photo.jpg');
Storage::disk('cdn-services')->copy('images/photo.jpg', 'images/photo-copy.jpg');
Storage::disk('cdn-services')->move('images/photo.jpg', 'images/new-photo.jpg');
```

### CdnServicesAuth – kayıt, giriş, token

[](#cdnservicesauth--kayıt-giriş-token)

Backend'de kullanıcı kaydı (registration token zorunlu olabilir), giriş ve CDN işlemleri için JWT almak:

```
use CdnServices\Facades\CdnServicesAuth;

// Kayıt (registration token config'ten veya 2. parametre ile)
$result = CdnServicesAuth::register([
    'email' => 'user@example.com',
    'password' => 'secret123',
    'name' => 'Ad Soyad',
]);
// $result['token'] → JWT (CDN_SERVICES_TOKEN olarak kullanılabilir)
// $result['user'] → id, email, name, role, createdAt

// Giriş
$result = CdnServicesAuth::login('user@example.com', 'secret123');
if ($result) {
    $jwt = $result['token'];
}

// Sunucu tarafında bir kullanıcı için JWT üret (CDN işlemleri için)
$tokenPayload = CdnServicesAuth::tokenForUser($userId, 'user@example.com', 'user');
$jwt = $tokenPayload['token'] ?? null;

// Kayıt için token zorunlu mu?
if (CdnServicesAuth::requiresRegistrationToken()) {
    // Config'te CDN_SERVICES_REGISTRATION_TOKEN tanımlı
}
```

### CdnServices facade

[](#cdnservices-facade)

```
use CdnServices\Facades\CdnServices;

CdnServices::put('images/photo.jpg', $fileContents);
$contents = CdnServices::get('images/photo.jpg');
$url = CdnServices::url('images/photo.jpg');
```

### Upload with `UploadedFile`

[](#upload-with-uploadedfile)

```
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

public function upload(Request $request)
{
    $request->validate(['image' => 'required|image|max:51200']); // 50MB

    $path = Storage::disk('cdn-services')->put('images', $request->file('image'));
    return response()->json([
        'success' => true,
        'path' => $path,
        'url' => Storage::disk('cdn-services')->url($path),
    ]);
}
```

### CdnServicesApi – meta, list, usage (kota), import, placeholder, signed URL, processed URL

[](#cdnservicesapi--meta-list-usage-kota-import-placeholder-signed-url-processed-url)

```
use CdnServices\Facades\CdnServicesApi;

$info = CdnServicesApi::getInfo($imageId);
$images = CdnServicesApi::listImages(['tag' => 'ürün', 'favorite' => true]);
CdnServicesApi::updateMeta($imageId, ['caption' => 'Yeni başlık', 'visibility' => 'private']);
CdnServicesApi::replace($imageId, $request->file('image'));
$usage = CdnServicesApi::usage(); // fileCount, totalSize, totalSizeMB, viewCountTotal, quotaBytes?, quotaMB?
$quotaRemaining = CdnServicesApi::getQuotaRemaining(); // null if no quota
$file = CdnServicesApi::importFromUrl('https://example.com/photo.jpg');
$file = CdnServicesApi::createPlaceholder(['width' => 800, 'height' => 600, 'text' => 'Placeholder']);
$result = CdnServicesApi::bulkDelete(['id1', 'id2']);
$signed = CdnServicesApi::getSignedUrl($imageId, 3600);
$url = CdnServicesApi::processedUrl($imageId, '800x600', 'webp', [
    'quality' => 80, 'fit' => 'cover', 'filter' => 'sepia', 'crop' => 'smart', 'watermark' => true,
]);
```

### Different backend disks (S3, Azure, etc.)

[](#different-backend-disks-s3-azure-etc)

```
Storage::disk('cdn-services')->put('images/photo.jpg', $fileContents, ['disk' => 's3']);
Storage::disk('cdn-services')->put('images/photo.jpg', $fileContents, ['disk' => 'azure']);
```

### Processed image URLs

[](#processed-image-urls)

```
$originalUrl = Storage::disk('cdn-services')->url($imageId);
$thumb = CdnServicesApi::processedUrl($imageId, 'thumbnail', 'jpeg');
$custom = CdnServicesApi::processedUrl($imageId, '800x600', 'webp', ['quality' => 75, 'watermark' => true]);
```

### Cloudflare Image Resizing

[](#cloudflare-image-resizing)

Backend’de Cloudflare Image Resizing açıksa, edge’de resize/format/quality için URL alınır:

```
$url = CdnServicesApi::cloudflareProcessedUrl($imageId, '800x600', 'webp', [
    'quality' => 80, 'fit' => 'cover', 'crop' => 'smart',
]);
// Backend GET /api/image/{id}/cloudflare-url ile aynı parametreler
```

Detay: CDN Services [docs/CLOUDFLARE\_IMAGE\_RESIZING.md](https://github.com/snowsoft/cdn-services/blob/main/docs/CLOUDFLARE_IMAGE_RESIZING.md).

### CdnServicesPdf – PDF depolama (blockchain, süreli session)

[](#cdnservicespdf--pdf-depolama-blockchain-süreli-session)

Backend'de `PDF_STORAGE_ENABLED=true` ise kullanılır; resim alanından bağımsızdır.

```
use CdnServices\Facades\CdnServicesPdf;
use CdnServices\Domain\Pdf\PdfDocument;
use CdnServices\Domain\Pdf\PdfSession;

if (!CdnServicesPdf::isEnabled()) {
    return; // PDF storage kapalı
}

// Yükle (value object döner)
// Yükleme veya HTML'den oluşturma (backend'de PDF_GENERATE_SERVICE_URL gerekir)
$doc = CdnServicesPdf::upload($request->file('pdf'));
// veya: $doc = CdnServicesPdf::generateFromHtml('Rapor', 'rapor.pdf');
if ($doc instanceof PdfDocument) {
    $id = $doc->id;
}

// Listele
$documents = CdnServicesPdf::list(); // list

// Süreli erişim session'ı al
$session = CdnServicesPdf::createSession($doc->id);
if ($session instanceof PdfSession) {
    $url = CdnServicesPdf::sessionUrl($session); // GET ile PDF açılır
    // veya: $session->url(config('cdn-services.base_url'));
}

// Sil
CdnServicesPdf::delete($doc->id);
```

**Constructor injection (DDD):** Uygulama sınıflarında port kullanmak için:

```
use CdnServices\Domain\Pdf\PdfStorageGatewayInterface;

class MyController extends Controller
{
    public function __construct(
        private PdfStorageGatewayInterface $pdfStorage
    ) {}
}
```

---

Customization
-------------

[](#customization)

**Custom base URL:** set `base_url` in `config/filesystems.php` for the `cdn-services` disk.

**Dynamic token:** in your service provider, when extending the disk, get config and call `$adapter->setToken(auth()->user()->cdn_token)` (or your logic) before returning the adapter.

---

Storage quota and exceptions
----------------------------

[](#storage-quota-and-exceptions)

When the backend has **USER\_STORAGE\_QUOTA\_BYTES** set, uploads (Storage `put`, API `replace`, `importFromUrl`, `createPlaceholder`) may return **413**. The adapter throws `CdnServices\Exceptions\QuotaExceededException` so you can catch and show a friendly message:

```
use CdnServices\Exceptions\QuotaExceededException;

try {
    Storage::disk('cdn-services')->put('images/photo.jpg', $contents);
} catch (QuotaExceededException $e) {
    return back()->with('error', 'Depolama limitiniz doldu.');
}
```

`CdnServicesApi::usage()` includes `quotaBytes` and `quotaMB` when a quota is set; use `getQuotaRemaining()` to show remaining space.

---

Troubleshooting
---------------

[](#troubleshooting)

ProblemCheckConnection refusedBackend running: `curl http://localhost:3012/health`UnauthorizedValid JWT in `CDN_SERVICES_TOKEN`; create token via backend `/api/auth/token`File not foundUse image ID (not path) when calling URL/meta APIsQuotaExceededExceptionBackend `USER_STORAGE_QUOTA_BYTES` limit reached; free space or increase quota---

API quick reference
-------------------

[](#api-quick-reference)

**Storage `put()` options:** `disk`, `caption`, `tags`, `folder`, `visibility`

**CdnServicesAuth:** `register`, `login`, `tokenForUser`, `getRegistrationToken`, `requiresRegistrationToken`

**CdnServicesPdf (DDD):** `upload(UploadedFile)`, `generateFromHtml(html, filename)`, `list()`, `createSession(documentId)`, `sessionUrl(PdfSession)`, `delete(documentId)`, `isEnabled()`

**CdnServicesApi:** `getInfo`, `listImages`, `updateMeta`, `replace`, `usage`, `getQuotaBytes`, `getQuotaRemaining`, `importFromUrl`, `createPlaceholder`, `bulkDelete`, `getSignedUrl`, `processedUrl`, `cloudflareProcessedUrl`

**Disk methods:** `exists`, `get`, `put`, `delete`, `copy`, `move`, `size`, `lastModified`, `mimeType`, `url`, `temporaryUrl`, `readStream`, `writeStream`, `files`

---

License
-------

[](#license)

MIT

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance88

Actively maintained with recent releases

Popularity11

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity28

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~6 days

Total

6

Last Release

62d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/4568234?v=4)[snowsoft](/maintainers/snowsoft)[@snowsoft](https://github.com/snowsoft)

---

Top Contributors

[![snowsoft](https://avatars.githubusercontent.com/u/4568234?v=4)](https://github.com/snowsoft "snowsoft (12 commits)")

---

Tags

filesystemlaravelimagestoragecdncdn-services

### Embed Badge

![Health badge](/badges/snowsoft-cdn-laravel-adapter/health.svg)

```
[![Health](https://phpackages.com/badges/snowsoft-cdn-laravel-adapter/health.svg)](https://phpackages.com/packages/snowsoft-cdn-laravel-adapter)
```

###  Alternatives

[unisharp/laravel-filemanager

A file upload/editor intended for use with Laravel 5 to 10 and CKEditor / TinyMCE

2.2k3.3M74](/packages/unisharp-laravel-filemanager)[zing/laravel-flysystem-obs

Flysystem Adapter for OBS

1211.2k](/packages/zing-laravel-flysystem-obs)[yoelpc4/laravel-cloudinary

Laravel Cloudinary filesystem cloud driver.

3343.0k](/packages/yoelpc4-laravel-cloudinary)[innoge/laravel-rclone

A sleek PHP wrapper around rclone with Laravel-style fluent API syntax

174.1k](/packages/innoge-laravel-rclone)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
