Weave 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

Fm Elfinder Php Connector Laravel Package

helios-ag/fm-elfinder-php-connector

Laravel wrapper for the elFinder PHP connector that lets you browse, upload, edit, and manage files and folders through elFinder's file-manager UI. Includes connector configuration and routes for quickly adding file management to Laravel apps.

View on GitHub
Deep Wiki
Context7

Getting Started

  • composer require helios-ag/fm-elfinder-php-connector. This is the server-side connector only — a Composer-packaged copy of Studio-42/elFinder's PHP connector. You still need the elFinder front-end (JS/CSS/images) separately via npm (elFinder), a CDN, or by copying Studio-42/elFinder's dist assets into public/.
  • Look first at the package's elFinderConnector and elFinder classes (they are global, non-namespaced classes — no PSR-4, no use statements) and at Studio-42/elFinder's php/connector.minimal.php for the option-array semantics. The connector is configured entirely by that array; there is no Laravel service provider, facade, or config file shipped.
  • Minimal Laravel wiring: a config array of roots, one route, one controller.
// config/elfinder.php
return [
    'roots' => [[
        'driver' => 'LocalFileSystem',
        'path'   => public_path('uploads'),
        'URL'    => url('uploads'),
        'accessControl' => function ($attr, $path, $data) {
            return auth()->check() && auth()->user()->is_admin;
        },
    ]],
];
Route::match(['get', 'post'], 'elfinder/connector', ElFinderController::class)
    ->middleware('auth');
public function __invoke()
{
    $connector = new \elFinderConnector(new \elFinder(config('elfinder')));
    $connector->run(); // echoes JSON + headers directly
}
  • First real use case: an admin-only media/file browser over public/uploads — browse, upload, rename, delete, and drag-drop — with PHP execution blocked and access gated by accessControl.

Implementation Patterns

Keep options in a builder class, not the controller. The connector has no Laravel integration, so the only thing worth testing is your options array. Put ElFinderConfig::forUser($user): array in a service and unit-test it; the controller stays a two-liner.

Per-user roots. The idiomatic pattern is one root per user with a dynamic path/URL and a strict accessControl callback:

'path' => storage_path("app/elfinder/{$user->id}"),
'URL'  => url("user-files/{$user->id}"),
'accessControl' => fn ($attr, $path, $data) =>
    str_starts_with(realpath($path), realpath(storage_path("app/elfinder/{$user->id}"))),

The realpath/prefix check matters — the callback receives arbitrary paths from the client, including .. segments.

Use attributes for extension policy, not just accessControl:

'attributes' => [
    ['pattern' => '/\.(php|phtml|phar|htaccess)$/i', 'read' => false, 'write' => false, 'locked' => true],
    ['pattern' => '/^\./', 'hidden' => true],
]

Bind events for auditing and side effects. $finder->bind('upload', fn ($cmd, &$result) => ...) (also mkdir, rm, rename, upload.presave) is where you hook Laravel logging, image resizing, or firing events. Mutate $result only if you know the connector's response shape.

Serve the connector outside the web middleware group. It emits its own Content-Type/Content-Length and streams file bodies for file/download commands. Wrap it in a lean group (auth, session, CSRF) rather than web, which drags in cookie encryption, debugbar, and response decorators that corrupt output.

Front-end init needs the connector URL and, if you don't fully exempt CSRF, customData:

elFinder.prototype.options.customData = { _token: window.csrfToken };

Lock the volume down with disabled commands — ['archive', 'extract', 'mkfile', 'netmount', 'netunmount'] removes whole classes of abuse without touching the filesystem layer. Pair with uploadMaxSize, uploadOrder, and acceptedName to constrain uploads.

Separate roots for public vs private. Public assets: LocalFileSystem under public_path(). Private documents: a second root under storage_path('app/...') with no URL set and a different accessControl. tmbPath/tmbURL must point at a writable, web-served directory or thumbnails silently fail.

Gotchas and Tips

  • Archived since 2018, 30 stars, zero dependents. Treat it as unmaintained code you happen to install. Expect PHP 8.x friction: deprecations on implicit nullable parameters, dynamic properties, and any lingering each()/create_function-era helpers. Test on your actual PHP version before committing; be prepared to fork or vendor the class files.
  • Global namespace classes. No autoloading conventions, no DI, no Laravel container hooks. new \elFinder(...) and new \elFinderConnector(...) are the whole API. Don't expect config/elfinder.php to be read by anything — you wrote that.
  • CSRF will bite you twice. elFinder POSTs upload/mkdir/rm to the connector. Either add the route to VerifyCsrfToken::$except (simplest) or pass _token via customData on every command. Forgetting this shows up as an HTML 419 page parsed as JSON.
  • Middleware poisoning the response. Debugbar, Clockwork, ShareErrorsFromSession, compression middleware, and anything that appends to the body will corrupt the connector's JSON or truncate downloads. If the file browser shows "invalid backend response," check the raw network tab first.
  • run() echoes; it does not return a Response. You cannot return $connector->run(), and any header() already sent by Laravel will collide. Keep the controller action free of output before run().
  • Session double-start. The connector may session_start() for upload chunking. With Laravel's session already started, you get warnings or a corrupted session payload. Usually harmless, but suppress or isolate if it leaks into the response body.
  • Path/URL mismatches are the #1 support issue. path must be an absolute, existing, writable directory; URL must be the matching web-accessible root, no trailing slash ambiguity. Get one wrong and you get an empty pane or broken thumbnails with no error.
  • Security defaults are permissive. The connector out of the box grants broad read/write. Always set accessControl, always block script extensions with attributes, and add nginx/Apache rules so the upload directory cannot execute PHP. Never point a root at base_path() or storage_path() wholesale.
  • Thumbnails and quotas fail quietly. Missing tmbPath write permissions or a too-small uploadMaxSize produce silent failures rather than exceptions. Check the php.ini upload_max_filesize/post_max_size values too — they override the connector's own limits.
  • Don't mix elFinder front-end and connector versions. The 2.x front-end expects 2.x response shapes; a mismatched npm elFinder against this 2018 connector gives confusing "unknown command" errors.
  • If you want maintenance, look elsewhere. barryvdh/laravel-elfinder wraps this same generation of code (equally dated). For new work, UniSharp/laravel-filemanager, spatie/laravel-medialibrary, or a small custom Livewire/Filament file browser will cost less than carrying a 2018 connector through PHP upgrades. If you do keep it, fork it into app/Support/ElFinder and own the code — you're one PHP minor release away from needing to anyway.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin