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

Ezplatform Site Api Laravel Package

se7enxweb/ezplatform-site-api

Site API extension for eZ Platform/Ibexa that simplifies content access with named queries, reusable Site API objects, and a cleaner Twig/template layer. It helps developers build content-rich sites faster while preserving the platform's native content model and features.

View on GitHub
Deep Wiki
Context7

Getting Started

First, calibrate your expectations: this is not a Laravel package. se7enxweb/ezplatform-site-api is a fork of Netgen's eZ Platform Site API — a Symfony bundle that wraps the eZ Platform / Ibexa v2-era public API (ezplatform-kernel) with a friendlier, read-optimised content model. There is no service provider, no config/site-api.php, no facade, and no Laravel discovery entry. Before writing any code, read composer.json in the tag:

  • require block: expect symfony/* constraints in the 3.4–4.4 range and ezsystems/ezplatform-kernel. Those constraints are the single biggest determinant of whether this can live in a Laravel app at all (Laravel 9+ ships Symfony 6 components).
  • autoload.psr-4: the fork may or may not have re-namespaced classes. Confirm whether it still ships Netgen\EzPlatformSiteApi\ or a vendor-specific namespace, and whether it declares replace/provide for the upstream package. If it does not, you cannot install it alongside netgen/ezplatform-site-api without class collisions.
  • version in the tag and whether 4.3.4 is a clean patch or carries an unmerged dependency bump.

Minimal integration path:

  1. composer require se7enxweb/ezplatform-site-api:4.3.4 into the Symfony/eZ app (or a standalone bootstrap), register the bundle in config/bundles.php, and ensure the kernel is booted with a valid siteaccess.
  2. Inject the Site service (the API entry point) into a controller or service — SiteAPI\Core\Site\Site exposes getContentService(), getFindService(), getLocationService(), getContentTypeService().
  3. Look first at lib/API/ (interfaces — this is the contract you code against) and lib/API/Values/ (Content, Location, ContentInfo, Field). Ignore the Core/ internals until you need to extend.
  4. First use case worth proving end-to-end: fetch a content item by ID, read one field, render its mainLocation children. If that round-trips, the wiring is correct.

Implementation Patterns

Code against the API interfaces, not the Core classes. Type-hint SiteAPI\API\Site and SiteAPI\API\Values\Content. This is what makes the fork swap-able and your code testable.

final class LandingController
{
    public function __construct(private \SiteAPI\API\Site $site) {}

    public function __invoke(int $locationId): Response
    {
        $location = $this->site->getLocationService()->loadLocation($locationId);
        $content  = $location->content;

        return $this->render('landing.html.twig', [
            'title'    => $content->getField('title')->value,
            'children' => $location->children->locations,
        ]);
    }
}

Prefer the Find/Filter services over the raw repository. getFindService()->findContent($query) / findLocations() and the filterContent() / filterLocations() variants are the day-to-day workhorses. The filter* methods operate on an already-loaded collection and avoid an extra search round-trip — use them for "children of the current location, narrowed by content type."

Traverse value objects rather than re-querying. Content gives you fields, getField(), mainLocation, contentInfo; Location gives you children, parent, siblings. Most N+1 problems in this ecosystem come from calling the load service inside a loop when the parent object already carried the data.

Use SiteAwareInterface for services that need the current siteaccess rather than injecting siteaccess strings around your codebase — the Site API resolves the active site for you, and that matters on multi-site installs.

In Twig, lean on the bundle's functions (ez_render_field, the Site API content/location rendering helpers) instead of hand-assembling field markup. If you inherit templates from a standard eZ install, keep the upstream view configuration and override per content type.

If you genuinely need this in Laravel, do not try to boot the Symfony kernel inside a Laravel request. Treat it as an out-of-process boundary: a small Symfony/console application that exposes content over HTTP or a queue, called from a Laravel HTTP client or job. Share only DTOs. Any in-process bridge means reconciling two container configurations and two siteaccess resolvers — it will cost more than it saves.

Pin exactly and test the upgrade. Use "se7enxweb/ezplatform-site-api": "4.3.4" (no caret) in the fork era, and put the package's own test suite plus one smoke test of your most complex query in CI.

Gotchas and Tips

  • 4.3.4 ships no changelog. The release note is only a compare link. Diff 4.3.3...v4.3.4 locally (git diff --stat, then read every changed file under lib/API/ and lib/Core/Site/) before bumping. Patches in forks routinely carry silent signature changes.
  • Fork hygiene is the real risk. Check the fork's last-commit date and issue count. If it lags upstream Netgen by many minor versions, you are accumulating unpatched fixes. Decide explicitly: fork (and own the merge burden) or upstream.
  • Class collision on co-install. Without a replace clause, installing this next to netgen/ezplatform-site-api yields duplicate PSR-4 roots and confusing "class not found / already declared" errors. composer why netgen/ezplatform-site-api first.
  • getField() throws on a missing field identifier. Guard with $content->hasField('x') or use the fields collection. Also check $field->isEmpty() — an empty field returns a Field object with a null-ish value, not null.
  • Relations are not fields. getFieldRelation() / relation fields return content or location objects and can trigger lazy loads. Eager-loading is your responsibility; there is no with().
  • findContent() returns a SearchResult, not an array. Iterate ->searchHits (each hit wraps ->valueObject) and read ->totalCount for pagination. Treating it as an iterable of Content objects is the most common first-day bug.
  • Siteaccess drives everything. Empty results usually mean the wrong siteaccess was resolved for the request (CLI commands and queue workers are the usual culprits). Verify with debug:container on the Site service and log the resolved site.
  • HTTP cache correctness. If you use the bundle's location-aware cache headers, mismatched X-Location-Id values leak wrong content into shared caches. Test with the cache enabled, not just in dev.
  • Debugging entry points: bin/console debug:container SiteAPI to see the wired services, debug:config for the bundle's tree, and the Symfony profiler's query panel for search round-trips. When a query returns nothing, dump the generated ContentQuery before touching your template.
  • Extension point: if you need custom behaviour, implement the API\* interfaces in your own namespace and alias them in services.yaml rather than subclassing Core\Site\* classes — the Core layer changes between patch releases more often than the API does.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings