PHPackages                             krma-cl/kcfinder-laravel - 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. krma-cl/kcfinder-laravel

ActiveLibrary

krma-cl/kcfinder-laravel
========================

Laravel integration for the maintained KCFinder continuation.

v1.4.3(1mo ago)018↓66.7%GPL-2.0-or-laterPHPPHP ^8.2CI passing

Since Jul 15Pushed 1mo agoCompare

[ Source](https://github.com/krma-cl/kcfinder-laravel)[ Packagist](https://packagist.org/packages/krma-cl/kcfinder-laravel)[ RSS](/packages/krma-cl-kcfinder-laravel/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (7)Dependencies (18)Versions (12)Used By (0)

KCFinder for Laravel
====================

[](#kcfinder-for-laravel)

Official Laravel adapter for [`krma-cl/kcfinder`](https://github.com/krma-cl/kcfinder-Resurrected). It connects Laravel filesystem, authorization, URL generation and native events to KCFinder while keeping the browser framework-independent.

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

[](#requirements)

- PHP 8.2 or newer.
- Laravel 12 or 13.
- A deployed KCFinder browser from `krma-cl/kcfinder`.

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

[](#installation)

```
composer require krma-cl/kcfinder-laravel:^1.4
php artisan vendor:publish --tag=kcfinder-config
```

Configure the disk and browser URL in `.env`:

```
KCFINDER_DISK=public
KCFINDER_URL_PREFIX=/storage
KCFINDER_BROWSER_URL=/kcfinder/browse.php
```

Define the authorization rule. The callback receives the operation and logical path:

```
use Illuminate\Support\Facades\Gate;

Gate::define('kcfinder.select', static function ($user, string $operation, string $path): bool {
    return $user->can('manage-files');
});
```

Operations include `browse`, `select`, `preview`, `upload`, `edit`, `copy`, `move`, `rename`, `delete` and `create_directory`.

Optional authenticated classic browser
--------------------------------------

[](#optional-authenticated-classic-browser)

Version 1.4.3 can route the classic browser through Laravel instead of exposing a PHP entrypoint inside `vendor`. It is disabled by default. Enable it only behind your application's authenticated middleware:

```
KCFINDER_HTTP_ENABLED=true
KCFINDER_HTTP_PREFIX=kcfinder
KCFINDER_SESSION_PATH=/absolute/writable/path/kcfinder-sessions
KCFINDER_UPLOAD_URL=/storage
```

```
// config/kcfinder.php
'http' => [
    'enabled' => true,
    'prefix' => 'kcfinder',
    'middleware' => ['web', 'auth', 'can:manage-files'],
    // ...
],
```

The browser is then available at `/kcfinder/browse.php`. The bridge:

- authorizes the request through the configured Gate;
- starts an isolated native session in a configurable writable directory;
- makes the CSRF token available on the very first request;
- injects the official operation observer without editing `vendor`;
- applies `nosniff`, a same-origin referrer policy and a configurable CSP;
- serves only the known browser entrypoints and safe static asset types.
- serves the legacy JavaScript and CSS bundle URLs without executing their minifier PHP wrappers inside the Laravel process;
- provides and restores the server variables required by functional PHP entrypoints.

The classic browser currently requires a local Laravel filesystem disk because its image editor and legacy file operations use physical paths. S3 and other remote disks remain supported for descriptors and URL resolvers, but not for this optional HTTP browser bridge.

Publish static assets without copying executable PHP files:

```
composer require krma-cl/kcfinder-bootstrap5-theme:^0.3.1
php artisan kcfinder:install-assets
php artisan kcfinder:install-assets --force
php artisan kcfinder:clear-cache
```

`kcfinder:clear-cache` removes generated bundles and the `.thumbs` tree. Adjust the CSP and middleware in configuration when the browser must be embedded in a different trusted origin. When the Bootstrap 5 theme package is installed, `kcfinder:install-assets`detects it and publishes `dist/bootstrap5` automatically. The generated application manifest records both installed package versions. The command also creates static base and theme bundles under `bundles/`. The authenticated HTML uses virtual, content-versioned URLs under `browser-assets/`, avoiding collisions with physical `js/` and `css/`directories on Apache. Those requests are resolved to the published bundles with the configured security headers. If assets have not been published yet, the bridge concatenates the trusted package sources directly without executing the legacy minifiers. `js_localize.php` is also rendered safely by the bridge and cannot terminate the Laravel process through its historical `die`. CSS bundles rebase relative `url(...)` references to the published `css/` or `themes//` directories. Embedded data, absolute and external URLs, `blob:` values and fragments remain unchanged, so theme icons and Jcrop resources resolve correctly from the virtual bundle endpoints. The authenticated route also mounts the package as a trusted external theme root, so KCFinder can load its icons and dynamic bundles without copying it inside `vendor/krma-cl/kcfinder/themes`.

Selecting files
---------------

[](#selecting-files)

Resolve a selected file as a stable JSON-compatible descriptor:

```
use Krma\KCFinder\Laravel\Facades\KCFinder;

$file = KCFinder::select('/01-actos/DO-20130614.pdf');

return response()->json($file);
```

```
{
  "name": "DO-20130614.pdf",
  "path": "/01-actos/DO-20130614.pdf",
  "url": "/storage/01-actos/DO-20130614.pdf",
  "mime": "application/pdf",
  "size": 184320
}
```

A `FileSelected` event is dispatched after an authorized selection.

Separate preview and selected URLs
----------------------------------

[](#separate-preview-and-selected-urls)

Applications no longer need to expose a storage path directly. Preview and final selected URLs can use different prefixes or temporary signed URLs:

```
KCFINDER_SELECTED_URL_PREFIX=/storage/transparencia
KCFINDER_PREVIEW_URL_PREFIX=/internal/kcfinder/preview
KCFINDER_PREVIEW_URL_TTL=300
```

```
$previewUrl = KCFinder::previewUrl('/images/photo.jpg');
$selectedUrl = KCFinder::selectedUrl('/images/photo.jpg');
```

For S3-compatible disks, setting a TTL makes the adapter request a temporary URL from Laravel's filesystem driver. If an application needs controller routes, authenticated previews or another strategy, bind the contracts in a service provider:

```
use Krma\KCFinder\Laravel\Contracts\PreviewUrlResolverInterface;
use Krma\KCFinder\Laravel\Contracts\SelectedUrlResolverInterface;

$this->app->bind(PreviewUrlResolverInterface::class, AuthenticatedPreviewResolver::class);
$this->app->bind(SelectedUrlResolverInterface::class, PublicAssetResolver::class);
```

Both resolvers receive a normalized absolute logical path. Preview resolution is authorized with the `preview` operation before the resolver is called.

Structured operation responses
------------------------------

[](#structured-operation-responses)

Version 1.1 adds a JSON-serializable operation result for upload, edit, move, rename, delete and directory creation. Wire it into the callbacks that already run after a successful KCFinder storage mutation:

```
use Krma\KCFinder\Laravel\Facades\KCFinder;

$result = KCFinder::reportUploaded('/images/photo.jpg');

return response()->json($result, $result->httpStatus());
```

```
{
  "success": true,
  "operation": "upload",
  "files": [
    {
      "name": "photo.jpg",
      "path": "/images/photo.jpg",
      "url": "/storage/images/photo.jpg",
      "mime": "image/jpeg",
      "size": 145408
    }
  ],
  "warnings": [],
  "meta": { "version": 1 }
}
```

Failures can retain a stable code, a useful message and their HTTP status:

```
use Krma\KCFinder\Laravel\Domain\OperationResult;

$result = OperationResult::failure(
    'upload',
    'MIME_NOT_ALLOWED',
    'The detected file type is not allowed.',
    415
);
```

If the file was saved but a secondary catalog operation failed, return a warning instead of a false upload failure:

```
use Krma\KCFinder\Laravel\Domain\OperationWarning;

$result = KCFinder::reportUploaded('/images/photo.jpg', [
    new OperationWarning(
        'CATALOG_SYNC_FAILED',
        'The file was saved, but catalog synchronization must be retried.'
    ),
]);
```

The adapter does not replace the legacy KCFinder JavaScript response automatically. Structured mode is opt-in and can be introduced endpoint by endpoint without breaking existing installations.

Automatic classic browser bridge
--------------------------------

[](#automatic-classic-browser-bridge)

KCFinder 4.8.1 exposes a neutral operation observer at the exact success points of the classic browser. The adapter registers `ClassicBrowserBridge` as its Laravel implementation, so integrations no longer need to call every `report*`method manually.

When the classic browser runs inside an already bootstrapped Laravel application, connect the observer in KCFinder's `conf/config.local.php`:

```
use KCFinder\Contract\OperationObserverInterface;

$_LOCALS['_operationObserver'] = app(OperationObserverInterface::class);
```

Do not bootstrap Laravel a second time from `config.local.php`. If `browse.php` is currently a completely independent public script, first expose it through the application's existing authenticated Laravel bootstrap or keep using the explicit `report*` methods until that boundary is available.

The bridge then performs this mapping automatically:

Classic operationLaravel eventupload, drag upload`FileUploaded`image edit, crop`FileEdited`move`FileMoved`copy`FileCopied`rename`FileRenamed`delete`FileDeleted`create directory`DirectoryCreated`rename directory`DirectoryRenamed`delete directory`DirectoryDeleted`Move, rename and delete take their authorized snapshot before the filesystem mutation. Bulk operations emit one event for each file that actually succeeds. A listener exception is logged by the core observer boundary and does not turn an already completed filesystem mutation into a false failure response.

Manual `report*` calls remain available for custom JSON endpoints. Do not use both mechanisms for the same operation, or the application will dispatch duplicate events.

Native Laravel events
---------------------

[](#native-laravel-events)

The reporter dispatches these events:

OperationEventupload`FileUploaded`edit/crop`FileEdited`move`FileMoved`copy`FileCopied`rename`FileRenamed`delete`FileDeleted`create directory`DirectoryCreated`rename directory`DirectoryRenamed`delete directory`DirectoryDeleted`File events contain the descriptor, SHA-256 checksum and authenticated user. Move and rename events contain both `previous` and `file` snapshots:

```
use Krma\KCFinder\Laravel\Events\FileMoved;

final class SynchronizeCatalog
{
    public function handle(FileMoved $event): void
    {
        $oldPath = $event->previous->file->path;
        $newPath = $event->file->path;
        $checksum = $event->file->checksum;
        $user = $event->user;
    }
}
```

This allows audit and catalog synchronization without scanning the complete storage tree.

### Correct order for destructive or relocating operations

[](#correct-order-for-destructive-or-relocating-operations)

Take the old snapshot before deleting, moving or renaming, then report only after the storage mutation succeeds:

```
$before = KCFinder::snapshot('/images/old-name.jpg', 'rename');

// Perform the authorized rename in the existing KCFinder integration.

$result = KCFinder::reportRenamed($before, '/images/new-name.jpg');
return response()->json($result, $result->httpStatus());
```

For deletion:

```
$deleted = KCFinder::snapshot('/images/photo.jpg', 'delete');

// Delete the file.

$result = KCFinder::reportDeleted($deleted);
```

Checksums are streamed instead of loading the whole file into memory. They can be changed or disabled:

```
KCFINDER_CHECKSUM_ALGORITHM=sha256
```

Set an empty value to disable checksums.

Compatibility
-------------

[](#compatibility)

The existing `KCFINDER_URL_PREFIX` and `temporary_url_ttl` configuration remain supported. Existing calls to `select()` and the previous two-argument `KCFinderManager` constructor continue to work. The automatic bridge requires KCFinder core 4.6 or newer.

The adapter keeps the HTTP bridge opt-in and never copies executable PHP files from `vendor`. Traditional standalone KCFinder installations remain supported.

Maintenance and community
-------------------------

[](#maintenance-and-community)

This official KCFinder integration is maintained by [KRMA](https://krmachile.com) together with its community of users and contributors. KRMA provides development, coordination and infrastructure to support the project's continuity.

Development
-----------

[](#development)

```
composer install
composer check
```

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance91

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 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 ~0 days

Total

11

Last Release

44d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2a8099dc8803d1ad65fe214703ce45a15640b4282c558e02b6e3d9753baaa53a?d=identicon)[krma-cl](/maintainers/krma-cl)

---

Top Contributors

[![krma-cl](https://avatars.githubusercontent.com/u/215206686?v=4)](https://github.com/krma-cl "krma-cl (22 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/krma-cl-kcfinder-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/krma-cl-kcfinder-laravel/health.svg)](https://phpackages.com/packages/krma-cl-kcfinder-laravel)
```

###  Alternatives

[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

80732.6M270](/packages/laravel-mcp)[psalm/plugin-laravel

Psalm plugin for Laravel

3365.5M359](/packages/psalm-plugin-laravel)[laravel/ai

The official AI SDK for Laravel.

1.1k6.4M360](/packages/laravel-ai)[illuminate/queue

The Illuminate Queue package.

20433.5M1.9k](/packages/illuminate-queue)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k31.8M166](/packages/laravel-cashier)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k17.6M165](/packages/laravel-pulse)

PHPackages © 2026

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