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

Direct Bundle Laravel Package

modera/direct-bundle

A small Modera bundle that integrates Direct functionality into Symfony/PHP applications, providing bundle configuration and service wiring for quick setup in projects already using Modera components.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. modera/direct-bundle is a Symfony bundle (2.x/3.x era, last tagged 2016-05-31), not a Laravel package. There is no service provider, no config/direct.php, no facade, no artisan command. composer require modera/direct-bundle in a Laravel app gets you a package whose bootstrapping expects Symfony\Component\HttpKernel\Bundle\Bundle, XML service definitions, and a KernelInterface. Unless you are maintaining a legacy Symfony app with an ExtJS frontend, the day-to-day leverage here is close to zero — treat it as a reference implementation of the ExtDirect protocol on PHP, not a dependency.

If you actually are on the target stack:

  1. Register the bundle in app/AppKernel.php, then confirm the routing import actually loaded:
    php app/console debug:router | grep -i direct
    
    If nothing shows up, the bundle's routing file wasn't imported and nothing else will work.
  2. Read these three things before writing a line of code, in this order:
    • DependencyInjection/Configuration.php — the only authoritative source for provider config keys (they moved between the 2014 and 2016 tags).
    • Resources/config/services.xml — shows whether providers are resolved by service ID, by controller class, or by a compiler-pass tag.
    • The endpoint controller — it handles both the API descriptor (?provider=x, returns Ext.app.REMOTING_API) and the batched RPC POST in the same action.
  3. Configure one provider pointing at one controller, hit the descriptor URL in a browser, and confirm you get a JS object back.
  4. Add the provider on the frontend:
    Ext.direct.Manager.addProvider(Ext.app.REMOTING_API);
    
    then call one method from the JS console before wiring it into a grid.

The first genuinely useful use case is replacing hand-written Ext.Ajax.request plumbing for one grid/store: expose list/read and save on an existing controller, point an Ext.data.proxy.Direct at it, and you get batched create/update/destroy in a single round trip.

If you are on Laravel: don't install it. Spend a half-day reading the protocol layer end-to-end and produce a conformance checklist of what the existing client depends on. That checklist — not the composer package — is your starting artifact.

Implementation Patterns

Symfony-native usage. The bundle wires three moving parts, and every real workflow rides one of them:

  • Provider registration. A "provider" maps a JS namespace (Ext.app.REMOTING_API / your own) to a set of PHP actions. Providers are declared in config and resolved through the DI container — by service id or class, depending on the tag. The registry is the contract between descriptor generation and dispatch; keep them derived from the same config.
  • Action exposure. Named service methods (or annotated controller methods, depending on tag/version) become RPC actions. The convention is namespace → action → method, and the client calls Client.Users.list(). This means your existing Symfony controller can already be the action class — no separate DTO, no REST serialization. That is the leverage.
  • Endpoint controller. Single route handles ?provider=x (returns api.js descriptor) and POST (batched JSON dispatch). Route it behind the same session/CSRF/auth firewall as the rest of your admin.

Laravel bridge (recommended pattern). Treat the Symfony bundle as spec, not code. The reusable core is ~300–600 lines:

  1. One POST /direct route → route model binding is irrelevant; you parse {action, method, data, tid} envelopes in the request.
  2. A dispatcher that iterates the batch, resolves each action/method against a registry of callables, and returns a per-call envelope:
    // success
    ['type' => 'rpc', 'tid' => $tid, 'action' => $action, 'method' => $method, 'result' => $result]
    // exception — still inside HTTP 200
    ['type' => 'exception', 'tid' => $tid, 'action' => $action, 'method' => $method,
     'message' => '…', 'where' => '…']
    
  3. One GET /direct/api.js that generates Ext.app.REMOTING_API from the same registry. Never let the descriptor and the dispatcher drift — a cached descriptor calling a deleted method yields opaque runtime method not found errors.
  4. A conformance harness: capture real request/response pairs from production, replay, diff until zero variance, then cut the client's provider URL over. Keep the old endpoint dark for one release cycle.

Per-action authorization. ExtDirect is batched, so a single HTTP request can carry many logical calls with different permission requirements. Laravel's single-route middleware model doesn't express this. Resolve authorization inside the dispatcher, per call, before execution, and return a denial as that call's exception envelope — not a 403 for the whole batch.

Adapter isolation. If you must run the bundle in-process for a dual-run phase, install it in an isolated Symfony microservice or separate PHP-FPM pool with its own composer.json, and proxy to it. Never put a 2016 dependency graph into Laravel's vendor tree — the transitive Symfony constraints will fight Laravel's own.

Gotchas and Tips

  • [READ-ONLY] subtree split. This repo is a split of an upstream monorepo. Any patch goes upstream to a project dormant ~nine years. Practically: you are vendoring and owning the code — assign a named owner.
  • PHP 8 breakage is real. Expect dynamic-property deprecations, create_function-era idioms, and untyped internals. On 8.1+ budget for a fork on day one, plus Composer platform constraints that refuse to resolve against Laravel 10/11.
  • The endpoint is dual-purpose. ?provider=x and the batched POST hit the same action. If you debug only the POST you'll never understand why the client boots into method-not-found errors — test the descriptor URL in isolation.
  • Partial batch failure must not fail the batch. ExtDirect expects per-call success/exception envelopes inside an HTTP 200. A single exception must not abort the loop, and must not leak stack traces to the client. Wrap each call in its own try/catch and sanitize message/where.
  • Session locking. Concurrent batches from the same session serialize on Laravel's session store; a dashboard firing several parallel requests will queue. Also: a 40-call batch can approach post_max_size and produce a silent empty request that looks like an auth bug — log the raw body size before dispatch.
  • CSRF / session expiry. Long-lived SPA admin sessions produce a 419 on token expiry, which ExtJS surfaces as a generic transport error with no retry path. Add a client-side handler and keep token TTL aligned with session TTL.
  • Auth divergence. The original Symfony firewall semantics vs. Laravel guards are easy to get subtly wrong — you can end up granting more than intended per-action. Write one test per action that asserts the permission boundary.
  • Descriptor caching. Version the generated api.js (or bust cache on registry change). Stale descriptors are the #1 source of "worked yesterday, broken today" ExtJS tickets.
  • Licensing. Verify the license file (Modera is usually MIT) before copying protocol logic into a first-party package — confirm, don't assume.
  • Debugging entry points. On Symfony: debug:router, debug:container to inspect provider/service ids, and the bundle's Configuration.php for true config keys. On Laravel (your port): log raw envelope + resolved callable + envelope-out per call; that trace is what you'll diff in the conformance harness.
  • Ramp-up cost is people, not code. ExtJS/ExtDirect is unknown territory to most engineers under ~35. Expect 2–3 weeks on the harness before productivity, longer for client-side ExtJS troubleshooting. Document the protocol semantics you implement — otherwise the next engineer reverse-engineers both ends.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource