ezsystems/ezautosave-ls
Legacy eZ Publish extension that automatically saves content drafts while editors work, reducing lost changes from session timeouts or crashes. Adds autosave behavior to the classic administration interface and content edit forms. Intended for legacy stack installations only.
Architecture fit — poor, and the framing is misleading. Despite the vendor/package shape, ezsystems/ezautosave-ls is not a Laravel package and not a general-purpose PHP library. The -ls suffix denotes an eZ Publish legacy stack extension: it ships no composer.json autoload block targeting application code, no service provider, no facade, no PSR-4 namespace. It is installed by the ezsystems/ezpublish-legacy-installer Composer plugin (package type ezpublish-legacy-extension), which unpacks files into the legacy extension/ directory for the legacy kernel to discover via settings/override. A Laravel application has no legacy kernel, no ezpublish module/view routing, and no legacy content datamodel, so there is nothing for the package to attach to. It is effectively a jQuery-era JavaScript widget plus a legacy PHP module that persists editing drafts.
Integration feasibility — near zero as a dependency; moderate as source material. The realistic path is not composer require but port-and-reimplement: lift the autosave client behavior (interval, debounce, dirty-check, flush-on-navigate) and the draft payload shape, then rebuild the server side as a Laravel route, FormRequest, policy, and a dedicated drafts table. Expect 1–2 days of archaeology to read the JS and legacy module, then 1–2 weeks to build a tested equivalent.
Technical risk — high, concentrated in licensing and lifecycle.
NOASSERTION. eZ Publish legacy was GPL-2.0; if this extension inherits that, any distributed derivative work carries copyleft obligations. This must be resolved by a human reading LICENSE/file headers before a single line is copied — copying code without clarity is the single largest risk here.Key questions for the team:
updated_at optimistic locking)?ezcontentobject_attribute semantics we don't have?Bottom line: do not adopt as a dependency. Treat it as a behavioral reference only, gated on license clearance.
Stack fit — none. Target stack is assumed to be Laravel 10/11 on PHP 8.2+, Composer 2, PSR-4 autoloading, queue workers, and a relational draft store. This package requires the legacy installer plugin, a legacy extension/ layout, and a legacy kernel bootstrap. Installing it into a Laravel skeleton produces either a plugin error or orphaned files with no execution path.
Migration path — reimplement, don't port.
POST /drafts/{draftable} → route-model binding, FormRequest validation, policy check on the underlying resource, write to a drafts table (id, draftable_type, draftable_id, user_id, payload JSON, version, created_at, updated_at). Use updated_at/version for optimistic concurrency.fetch/Axios with X-CSRF-TOKEN, keepalive: true for unload flushes, and a visibility-change flush. Do not resurrect the jQuery transport.Compatibility. Incompatible with PHP 8.1+ (legacy stack code relies on removed constructs), incompatible with Laravel's routing/kernel, and incompatible with modern autoloading. If any eZ legacy instance genuinely exists in the estate, the extension could be pinned there — but that instance is itself the problem to be retired, not extended.
Sequencing.
Maintenance. Zero upstream. Archived repository, no releases since February 2019, no maintainer obligation. Any fork becomes wholly ours — including the security surface of copied JS and PHP.
Support. No vendor support path; eZ Systems/Ibexa have moved on from the legacy kernel. No CVE monitoring, no advisory feed, no patch SLA. If we own a fork, we own the response plan for any vulnerability found in the copied code or its assumptions (session handling, unserialization, file paths).
Scaling. The original writes to the legacy content store on each autosave tick, which is write-amplification by design: N concurrent editors × 1 write per interval, all landing in the same tables that serve reads. A naive port reproduces that. Mitigations to specify up front: debounce plus dirty-field diffing (skip no-op saves), a dedicated drafts table isolated from primary content tables, JSON column rather than one row per attribute, and a queue for any post-processing. Budget for storage growth and prune aggressively.
Failure modes to design against.
Ramp-up. Code volume is small, but domain cost is not trivial: interpreting the legacy content model (ezcontentobject_attribute and friends) requires someone with eZ Publish background. Realistic onboarding: half a day to read the JS, 1–2 days to produce a trustworthy behavior spec, then standard Laravel velocity. Total cost of the "reimplement from spec" route is bounded and predictable; total cost of the "make the dependency work" route is unbounded and should be declined.
How can I help you explore Laravel packages today?