ezsystems/ezprestapiprovider-ls
Provides a REST API provider for the eZ Publish Legacy Stack, letting applications access content and repository data through RESTful endpoints. Useful for integrating legacy eZS Publish sites with modern services and decoupled front ends.
This is a Legacy Stack (LS) bridge: it exposes legacy-kernel content (eZContentObject and friends) through the eZ Publish REST API v2, for installs where eZ Publish 5 still runs the legacy bridge alongside the Symfony stack. It does not run standalone, has no Symfony bundle configuration of its own, and has been archived since 2014 — treat it as maintenance-only work on an existing install, not something to adopt.
Minimum path to first call:
ezpublish_legacy/ present, legacy kernel bootstrapped from Symfony). Without it, nothing in this package can execute.ezpublish_legacy/extension/ezprestapiprovider and activate it in the legacy extension list.php ezpublish/console cache:clear) and legacy (php bin/php/ezcache.php --clear-all). Half-cleared caches are the single most common "it doesn't work" cause.# create a session, then reuse the cookie
curl -i -X POST https://example.com/api/ezp/v2/user/sessions \
-H 'Accept: application/vnd.ez.api.Session+json' \
-H 'Content-Type: application/vnd.ez.api.SessionInput+json' \
-d '{"SessionInput":{"login":"admin","password":"publish"}}'
curl -i https://example.com/api/ezp/v2/content/objects/42 \
-H 'Accept: application/vnd.ez.api.Content+json' \
-b 'EZPublishSessionID=<id>'
Where to look first in the repo: the README, the legacy settings/*.ini* files (that's where providers are registered), and classes/ (the provider implementations themselves). The ini files answer "what is actually exposed" faster than any doc.
The realistic first use case is a read path: pull content objects, locations, and search results into a separate front end or integration while editors keep working in the legacy admin.
Authenticate once, reuse the session. Session tokens expire; wrap the client with a re-login-on-401 interceptor rather than logging in per request. Basic auth per call works but is far slower on the legacy stack.
Read-heavy, write-light. Reads (content, locations, sections, search) are the well-trodden path. Writes through the legacy provider are the least exercised code in this package — if you need create/update, prefer the legacy admin or the modern stack and treat REST writes as unsupported until you've proven them.
Normalize immediately. Responses are legacy-shaped (Content → Fields → fieldValue arrays, string-typed everything, numeric IDs as strings). Map into your own DTOs at the boundary; never let fieldValue structures leak into application or template code. Field identifiers are your stable keys, not field IDs.
Use server-side querying, not client-side filtering. The content query endpoint accepts criteria, sort clauses, limit and offset. Mirror the ezcontentobject queries you'd write in legacy PHP instead of fetching a page and filtering in your app — the legacy stack will not forgive large result sets.
Put a cache in front of it. Legacy content fetching is slow and this package provides no useful invalidation. Cache GETs by object ID + version + the authenticated user's identity (visibility differs per user, so never cache anonymously-fetched content for authenticated callers). Purge on a TTL or a legacy content-publish hook.
One seam for migration. Hide everything behind a small interface — something like ContentReader::getById(), search() — with this package as one implementation. The supported path forward is the modern REST API on eZ Platform/Ibexa; when you migrate, you swap the implementation, not the call sites.
Test against recordings. Booting this stack in CI is painful. Record real HTTP exchanges as fixtures and test your client and DTO mapping against those; keep a tiny manual smoke checklist for the stack itself.
Content-Type before decoding. Some legacy failure modes return an HTML error page with a 200 or 500; a naive json_decode turns that into a confusing null instead of the actual stack trace..ini.append.php overrides, order in the extension activation list, and typo'd keys fail quietly. Grep the extension for eZINI::instance( to see which settings are actually read, rather than trusting the sample ini.var/log/, and the Symfony log. A blank response is usually a legacy PHP fatal — a missing class in the legacy autoloader — not an API problem.classes/ and registering them in the legacy ini. If you go there, fork the repo, pin by commit, and keep your patch set minimal — you are now the maintainer.How can I help you explore Laravel packages today?