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

Editor Hub Bundle Laravel Package

jims/editor-hub-bundle

Editor Hub Bundle provides a centralized hub for editor integrations in PHP applications, helping you organize editor configuration and related workflows in one place. It offers a configurable, lightweight approach to managing editor setup and keeping features consistent across projects.

View on GitHub
Deep Wiki
Context7

Getting Started

First, verify the package identity and platform. Despite the "Laravel developer" framing, jims/editor-hub-bundle is a Symfony bundle (Symfony 2/3/4) wrapping Baidu's UEditor/UMEditor. There is no ServiceProvider, no config/editor-hub.php, no facade — so on a Laravel codebase the realistic path is to treat it as a reference implementation and port the ~200 lines you actually need, or to fork it. Either way, start by reading the source, not the docs:

composer show jims/editor-hub-bundle --all   # check php + symfony/* constraints first

If you see php: >=5.5 and symfony/symfony: ~2.8|~3.0, it will not install alongside modern Symfony or Laravel — clone the repo and read it instead of fighting Composer.

Where to look first (in order):

  1. DependencyInjection/Configuration.php — every tunable option (upload paths, allowed extensions, editor flavour).
  2. Controller/* — the UEditor server endpoint (action=config, uploadimage, catchimage, …). This is the piece you are really porting.
  3. Resources/config/routing.yml — the route the editor's serverUrl must point at. Note this route is the protocol surface — UEditor hard-codes a single catch-all endpoint and multiplies operations through an action query string.
  4. Resources/views/ (or the Twig extension) — the snippet that emits <script> + UE.getEditor(...) and merges the config blob. Translate to Blade.

First use case — get GET /ueditor/server?action=config returning the JSON config blob, then render an editor instance pointing at it. That is the whole protocol handshake. Once config works, uploads are the only meaningful remaining work. On Laravel:

// routes/web.php
Route::any('/ueditor/server', [UEditorController::class, 'handle'])
    ->middleware(['auth', 'can:edit-content']);

// Blade
<div id="editor"></div>
<script src="/vendor/ueditor/ueditor.config.js"></script>
<script src="/vendor/ueditor/ueditor.all.js"></script>
<script>
  UE.getEditor('editor', { serverUrl: '/ueditor/server' });
</script>

If instead you are on a real Symfony 4.4 app with Chinese-speaking authors, composer require jims/editor-hub-bundle, register the bundle in config/bundles.php, and consume the Twig helper. That is the intended path — but only for Symfony ≤4.4.

Implementation Patterns

Treat the endpoint as a protocol, not a REST API. UEditor multiplexes every operation through one URL + action query parameter. Do not try to be RESTful about it.

public function handle(Request $request)
{
    return match ($request->query('action')) {
        'config'        => response()->json($this->config()),
        'uploadimage'   => $this->storeImage($request),
        'uploadfile'    => $this->storeFile($request),
        'catchimage'    => $this->fetchRemote($request), // if you must
        default         => response()->json(['state' => 'unknown action'], 400),
    };
}

Mirror the response shape exactly. UEditor expects a specific JSON envelope — {"state": "SUCCESS", "url": "...", "title": "...", "original": "...", "type": "..."} for uploads and {"state": "ERROR: ..."} on failure. Emit that shape from your own controller and the front-end will "just work" regardless of backend.

Centralize config in PHP, not in the vendor JS. The config action should return the full config.json blob so the editor self-configures. Keep a single source of truth:

protected function config(): array
{
    return [
        'imageActionName'   => 'uploadimage',
        'imageFieldName'    => 'upfile',
        'imageAllowFiles'   => ['.png', '.jpg', '.jpeg', '.gif', '.webp'],
        'imageMaxSize'      => 5 * 1024 * 1024,
        'imageUrlPrefix'    => '',
        'imagePathFormat'   => '/uploads/editor/{yyyy}{mm}{dd}/{rand:8}',
        // ...same block for fileActionName, scrawlActionName, etc.
    ];
}

Sanitize on write AND on read. UEditor is a stored-HTML editor. Run HTMLPurifier (or mews/purifier on Laravel) on what you save and again on what you render, because legacy content authored before your sanitizer existed still flows through. This is a security invariant, not a nicety.

Lock down the upload handler explicitly. Do not port the original's extension-string validation. Enforce: size cap from config, MIME sniff (finfo / Laravel's image/mimes rule), non-executable storage location (outside public/, or S3), randomized filenames, and no HTML/SVG/JS in the allowed set.

Symfony-side, if you genuinely use the bundle: register editors as tagged services (editor_hub.editor tag) and let the registry discover them. Shared config profiles let you define one toolbar and reuse across editors; the Twig helper emits both the <script> includes and the UE.getEditor() call. Add a custom adapter by implementing the bundle's editor adapter interface — that is the documented extension point.

Assets. Under Symfony ≤4.4 the bundle uses the old asset conventions (possibly Assetic). If you port to Laravel, drop assets under public/vendor/ueditor/ and copy them via a publish command; under Vite, copy them as static files rather than trying to bundle them — the editor assumes a global UE and a runtime-computed serverUrl, so bundling breaks path resolution.

Testing. Write a smoke test per action (config, upload success, upload rejection, oversized upload). These are the ones that fail silently later.

Gotchas and Tips

It will not install on modern stacks. Symfony 4.4 is EOL (Nov 2023), Symfony 2/3 long dead. Laravel 10/11 needs PHP 8.1+, which conflicts on symfony/http-foundation/symfony/routing. composer require will fail loudly or force --ignore-platform-reqs and a cascade of patches. Decide up front whether you are porting or using — do not drift into a half-fork.

Zero dependents, one maintainer, 10 stars. No security advisories will ever be published for this fork. Treat every byte as unmaintained code you now own. Pin the commit, vendor the assets, and open it in the browser on Chrome and Safari before committing — the editor is iframe-based and depends on deprecated DOM APIs that nobody has tested against current browsers.

The upload endpoint is historically the weak point. UEditor's canonical PHP connector has a poor security record (extension-based validation, web-reachable storage, path traversal). Do not call the bundle's handler as-is. Write your own using your framework's file validation, and store files where nothing executes.

serverUrl must be absolute from the browser's view. If the editor is served from /admin/ and the endpoint resolves relatively, config and uploads break with opaque errors. Log the resolved URL server-side once and verify it.

Silent failure modes to instrument:

  • The config action returning malformed JSON — the editor loads but every toolbar is empty.
  • Upload response state not exactly "SUCCESS" — the editor treats anything else as failure, including "success".
  • Asset publishing silently not running after a deploy — a blank editor with no console error.
  • Stored XSS from legacy content that predates your sanitizer.

Add a /ueditor/server?action=config health check to your uptime monitor; it is the cheapest signal that the whole integration is alive.

Config quirks. UEditor merges the config blob over defaults — if a key is missing it falls back, if it is present-but-wrong-type it breaks silently. Keep imagePathFormat/filePathFormat in the exact {yyyy}{mm}{dd}{rand:8} placeholder syntax; a near-miss produces a valid but colliding filename.

Extension points. On Symfony, the adapter interface + tagged services are the sanctioned way to add a second editor. On Laravel, skip all of that — the protocol is the interface; anything that answers action=config and action=upload* in the right envelope is a valid backend.

Ramp-up cost is real and mostly sunk. Budget 1–2 weeks to become productive, and roughly that again when you next upgrade PHP. That is the dominant lifecycle cost and it does not appear in the integration estimate. If you have a legacy UEditor corpus, run a content audit first (sample stored HTML, count sanitizer-affected records) before committing to either path.

Prefer replacement if the requirement is "any WYSIWYG." TipTap/ProseMirror, CKEditor 5, and TinyMCE all have current Laravel and Symfony integrations plus a security process. The only defensible reason to stay on this stack is byte-compatible rendering of existing UEditor-authored content, or an existing Symfony ≤4.4 admin panel with trained Chinese-speaking authors. Otherwise, decline and fund the exit now.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console