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

Richfilemanager Php Laravel Package

servocoder/richfilemanager-php

Laravel package that integrates the RichFilemanager file browser via a PHP connector, enabling browsing, uploading, editing, and managing files and folders with configurable routes, middleware, and storage settings for quick setup.

Deep Wiki
Context7

Getting Started

What you're actually installing. This is the server-side half of RichFilemanager: a PHP front controller that speaks the RichFilemanager JSON protocol (list, upload, rename, copy, move, delete, create-folder, thumbnails). The JS widget is shipped separately; this package only handles the filesystem side. Everything in it predates Laravel 6 — there is no service provider, no facade, no publishable config, no migrations. Treat it as a drop-in script you wrap, not a package you "install into" Laravel.

Step 1 — install and find the entry point.

composer require servocoder/richfilemanager-php
ls vendor/servocoder/richfilemanager-php/

Look first at two files, in this order:

  1. config/config.php (or connectors/php/config/config.php) — the entire behaviour of the connector is this one returned array: options.uploadDir, options.uploadURL, options.thumbsDir, security.readOnly, security.extensions, exclude.dirs, exclude.files. Read it before writing a line of code.
  2. connector.php — the front controller. Note whether it uses __DIR__ (relative paths are safe) or getcwd() (relative paths depend on where you invoke it).

Step 2 — give it a home outside vendor/. Copy the connector (and its application//config/ siblings) into public/filemanager/ so the paths it computes stay stable, then edit the copied config. Never edit inside vendor/ — the next composer update silently reverts your config.

Step 3 — point the widget at it.

new RichFilemanager('#fm', {
  fileConnector: '/filemanager/connector.php',
});

Step 4 — do the first real use case before anything else: serve a per-user uploads folder.

// public/filemanager/config/config.php  (edited)
'options' => [
    'uploadDir' => base_path('storage/app/public/uploads/'),
    'uploadURL' => '/storage/uploads/',
    'thumbsDir' => '.thumbs',
],

Then harden the web server so PHP does not execute there (location ~ \.php$ { deny all; } in the uploads dir), and php artisan storage:link. Browse, upload one image, confirm a thumbnail appears in .thumbs. If that works, the connector is wired correctly; everything after is scoping.

Implementation Patterns

Pattern A — standalone front controller (recommended). Keep connector.php in public/filemanager/ and let it run without Laravel's kernel. Auth is enforced by a small bootstrap at the top of the connector:

require __DIR__.'/../../vendor/autoload.php';
$app = require_once __DIR__.'/../../bootstrap/app.php';
$app->make(Illuminate\Contracts\Http\Kernel::class)->bootstrap();
$user = auth()->user();
if (!$user) { http_response_code(403); exit; }

This gives you the Laravel session and Auth without fighting the connector's own request/response lifecycle. It's the least surprising integration and survives package upgrades.

Pattern B — route require. If you'd rather have middleware, quotas, or request logging, mount it as a route:

// routes/web.php — must be registered before any catch-all
Route::any('/filemanager/connector', function () {
    return require public_path('filemanager/connector.php');
})->middleware(['auth']);

Works, but read the Gotchas on __DIR__ and exit semantics before shipping this.

Pattern C — per-user / per-tenant roots. The config is a plain PHP array, so generate it at runtime instead of storing it in a file:

public/filemanager/config/config.php:
<?php
 $base = storage_path('app/tenants/'.auth()->user()->tenant_id);
 return require base_path('config/richfilemanager.php');  // with $base injected

Or wrap the whole thing: a thin connector.php sets $overrides, then requires the stock config and array_replace_recursives. This is the idiomatic extension point — there is no event system, so config injection is your only hook short of subclassing.

Pattern D — role-scoped read-only views. For "browse the media library but don't touch it" screens, set security.readOnly => true and security.extensions => ['jpg','png','webp'] in a second, separate connector instance. Run two connectors rather than trying to switch config per request: the connector assumes one config per front controller.

Integration tips.

  • Exempt the connector route from CSRF (app/Http/Middleware/VerifyCsrfToken.php, $except = ['filemanager/*']) — the widget's XHRs don't carry your token.
  • Use Route::any, not get/post: listings are GET, mutations are POST.
  • Keep uploadDir (filesystem) and uploadURL (web path) in lockstep. They are two separate strings and the connector will happily produce links to files it can read but the browser can't.
  • Exclude .thumbs in exclude.dirs so thumbnails don't appear as user folders, and keep .htaccess in exclude.files.
  • For S3/object storage: don't. The connector is fopen/is_dir/rename all the way down. Mount a filesystem or use Laravel's Flysystem behind your own endpoint.
  • Pin the version. "servocoder/richfilemanager-php": "1.*" plus a committed composer.lock; there has been no release since June 2018.

Gotchas and Tips

  • PHP 8 will hurt. 2018-era code routinely hits create_function-style closures, dynamic properties, and each()-adjacent patterns. Run it under your target PHP version before you build anything on top of it; budget for a handful of two-line patches.
  • __DIR__ vs CWD. If the connector resolves config/config.php relative to getcwd(), invoking it from a Laravel route (where CWD is the public root) breaks with "config not found". Check line one of connector.php; if it's getcwd(), prefer Pattern A or chdir() first.
  • It calls exit. Many connector versions terminate the request directly rather than returning a response. Inside a Laravel route that bypasses terminable middleware and can leave the session unclosed — another reason Pattern A is safer.
  • Errors are JSON, not exceptions. A failure returns {"status":"error","message":...} and dies, so Laravel's handler and your log never see it. Wrap the route (or the bootstrap) in try/catch, Log::error() the throwable, and keep APP_DEBUG=false in production — the connector will leak absolute paths otherwise.
  • Path traversal is on you. serverRoot/fileRoot control whether paths outside the upload root are reachable. Leave serverRoot => false unless you have a concrete need, and never let fileRoot come from a query string or a raw request parameter.
  • Permissions and thumbnails. Thumbnail generation fails quietly when the web user can't write .thumbs. Fix with chown -R www-data:www-data on uploadDir; 755/644 for everything else. On nginx, raise client_max_body_size or uploads over the default 1 MB return a 413 that looks like a connector error.
  • Uploads under public/ are a liability. If you must serve from there, add an nginx/Apache rule killing PHP execution in the upload directory. Better: storage/app/public plus a symlink.
  • Case sensitivity. uploadURL and fileConnector that work on macOS will 404 on Linux for a single capital letter. Verify the exact path the widget requests in devtools, not from the source.
  • Extension points are thin. Realistically: (a) override the config array, (b) subclass the connector's handler class if the release exposes one, (c) put middleware in front of the route. There's no plugin/event surface — if you need virus scanning or quota enforcement, do it in the route before the require.
  • Version drift. The JS widget and this connector are versioned separately and the protocol changed over the years (mode parameters, response shapes). Match a connector tag to the RichFilemanager build you actually ship, and smoke-test list → upload → rename → delete after any bump.
  • Verdict. Fine as a low-effort internal file browser behind auth on PHP 7.x, where you control the upload path and the config. Poor fit if you need object storage, multi-tenancy at scale, or PHP 8.3 — in that case wrap Flysystem in ~150 lines of your own controller and keep the RichFilemanager JS UI pointed at it.
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.
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json
refinery29/php-cs-fixer-config
hotmeteor/eco-env
mvaliolahi/hydrate
wearede/tbcpay-php
parsnick/steak
thibaud-dauce/mattermost-php
multilinguals/apollo-client
antaresbr/collection
kr0lik/phpstan-rules