Skip to content
docsv0.34.0

LiveController

The panel's live wire: `POST {route}/live` — one endpoint over the ONE registry the page compiled with, so a component of the panel's own and a component a guest declared take their actions through the same door (greenhouse decisions/0211). The registry is rebuilt from the SAME reading the page used ({@see BootedPlugins}, then {@see ComponentBook::forSections()}): the sections are discovered per request on both surfaces, so an envelope minted while painting a page RESOLVES here, and a `RenderEffect` from a host component can repaint a guest's. **Resolving is not verifying, and the key is the app's.** This endpoint verifies with the PANEL's codec ({@see AdminSettings::signingSecret()} — `admin.secret`, else `live.secret`, else one derived from this install), while a guest's renderer signed with the guest package's own key. An app that declares neither gives the two different derived keys, and a guest's envelope is refused `400 invalid_signature` — loud, per call, never silent. Declaring one house key (`live.secret`) is what makes host and guest sign alike; measured both ways on a fresh app. The residue is named in the README: {@see \Milpa\Admin\Section\DeclaredView} does not receive the panel's codec, so a guest cannot borrow the host's key without the app saying so. **Behind the same door.** The route carries the panel's effective middleware stack — the gate of greenhouse decisions/0204 and 0206, whatever the app declared — because a wire outside the door would be a hole: an unauthenticated caller could act on any mounted component of any section. The endpoint adds no second policy of its own; it names WHO acted (the actor the gate authenticated, with the component scopes) so a component whose state is bound to a principal recognises its owner. Nobody signed in is `null` — the panel invents no identity, exactly as the topbar does not. The page session the CSRF token is bound to comes from the REQUEST BODY: `LiveBoot::issue()` minted it when the page was rendered and the runtime echoes it as `sessionId` on every action. No cookie carries it — a cookie another page set is not this page's session.

LiveController::__construct()

public function __construct(Milpa\Interfaces\Di\DIContainerInterface $container, object $self, Milpa\Live\Contracts\Transport\StateTransferCodecInterface $codec, Milpa\Live\Contracts\Security\CsrfGuardInterface $csrf, Milpa\Admin\AdminSettings $settings, ?Milpa\Interfaces\Event\MilpaEventDispatcherInterface $events = null):

Parameters

Parameters of __construct()
NameTypeDescription
$containerMilpa\Interfaces\Di\DIContainerInterface
$selfobjectthe admin plugin instance — the one section provider the panel can count on without a kernel
$codecMilpa\Live\Contracts\Transport\StateTransferCodecInterface
$csrfMilpa\Live\Contracts\Security\CsrfGuardInterface
$settingsMilpa\Admin\AdminSettings
$events?Milpa\Interfaces\Event\MilpaEventDispatcherInterface

LiveController::live()

public function live(Psr\Http\Message\ServerRequestInterface $request): Psr\Http\Message\ResponseInterface

Handle one component interaction: `{action, state, payload, sessionId, csrfToken}` in, re-rendered HTML + a fresh envelope out.

Parameters

Parameters of live()
NameTypeDescription
$requestPsr\Http\Message\ServerRequestInterface