incomingRequest = $incomingRequest; $this->tpl = $tpl; $this->response = app()->make(Response::class); // initialize if (method_exists($this, 'init')) { app()->call([$this, 'init']); } if (! property_exists($this, 'view')) { throw new LogicException('HTMX Controllers must include the "$view" static property'); } self::dispatchEvent('end', $this); } /** * Sets the response header to trigger an htmx event * **/ public function setHTMXEvent(HtmxEvent|string $eventName): void { $this->headers['HX-Trigger'] ??= []; $this->headers['HX-Trigger'][] = $eventName instanceof HtmxEvent ? $eventName->event() : $eventName; } /** * Queue one or more client (HTMX) events on the HX-Trigger response header. * Accepts HtmxEvent enum cases (preferred) or raw strings. */ public function emit(HtmxEvent|string ...$events): void { foreach ($events as $event) { $this->setHTMXEvent($event); } } /** * Gets the response * **/ public function getResponse($fragment): Response { $this->response = tap( $this->tpl->displayFragment($this::$view, $fragment ?? ''), function (Response $response): void { // Merge queued HX-Trigger events from BOTH the controller and the template // (set()ing each bag separately would let the second silently overwrite the // first), expand legacy aliases, and emit the comma-separated list once. $triggerEvents = array_merge( $this->headers['HX-Trigger'] ?? [], (array) ($this->tpl->getHeaders()['HX-Trigger'] ?? []) ); foreach ([$this->headers, $this->tpl->getHeaders()] as $headerBag) { foreach ($headerBag as $key => $value) { if ($key === 'HX-Trigger') { continue; } $response->headers->set($key, is_array($value) ? implode(',', $value) : $value); } } if (! empty($triggerEvents)) { $response->headers->set('HX-Trigger', HtmxEvents::triggerHeader($triggerEvents)); } }, ); return $this->response; } /** * Execute an action on the controller. * * @param string $method * @param array $parameters * @return \Symfony\Component\HttpFoundation\Response */ public function callAction($method, $parameters) { return $this->{$method}($parameters); } /** * Handle calls to missing methods on the controller. * * @param string $method * @param array $parameters * @return mixed * * @throws \BadMethodCallException */ public function __call($method, $parameters) { throw new BadMethodCallException(sprintf( 'Method %s::%s does not exist.', static::class, $method )); } }