1: <?php
2:
3: namespace LaravelUi5\Core\Controllers;
4:
5: use Illuminate\Http\Response;
6: use Illuminate\Routing\Controller;
7: use Illuminate\Support\Facades\Blade;
8: use Illuminate\Support\Facades\File;
9: use LaravelUi5\Core\Contracts\Ui5Context;
10: use LaravelUi5\Core\Exceptions\MissingCardManifestException;
11: use LaravelUi5\Core\Services\ExecutableHandler;
12: use LaravelUi5\Core\Ui5\Contracts\ConfigurableInterface;
13: use LaravelUi5\Core\Ui5\Contracts\ParameterizableInterface;
14: use LaravelUi5\Core\Ui5\Contracts\Ui5CardInterface;
15:
16: /**
17: * Controller for serving UI5 Card manifests with embedded data.
18: *
19: * This controller is invoked only for routes that resolve to UI5 Cards.
20: * The Ui5Context middleware guarantees that `$context->artifact` is
21: * an instance of {@see Ui5CardInterface}.
22: *
23: * Responsibilities:
24: * - Locate the Blade-based card manifest by convention
25: * (`ui5/{app}/resources/ui5/cards/{slug}.blade.php`).
26: * - Resolve the associated {@see DataProviderInterface}.
27: * - If the provider implements {@see ParameterizableInterface},
28: * inject validated request parameters.
29: * - If the provider implements {@see ConfigurableInterface},
30: * inject resolved settings.
31: * - Execute the provider and render the manifest with the resulting data.
32: * - Return the compiled manifest as JSON to the client.
33: *
34: * Notes:
35: * - Cards are read-only artifacts; providers must not mutate application state.
36: * - The manifest Blade file is expected to output valid JSON.
37: * - Missing manifests result in HTTP 404; execution always returns 200,
38: * even for empty data arrays.
39: */
40: class CardController extends Controller
41: {
42: public function __invoke(
43: Ui5Context $context,
44: ExecutableHandler $dataProviderHandler,
45: string $app,
46: string $slug,
47: string $version
48: ): Response
49: {
50: /** @var Ui5CardInterface $card */
51: $card = $context->artifact;
52:
53: $manifestPath = base_path("ui5/{$app}/resources/ui5/cards/{$slug}.blade.php");
54: if (!File::exists($manifestPath)) {
55: throw new MissingCardManifestException($manifestPath);
56: }
57:
58: $data = $dataProviderHandler->run($card->getProvider());
59:
60: $compiled = Blade::render(File::get($manifestPath), [
61: 'data' => $data,
62: ]);
63:
64: return response($compiled, 200)->header('Content-Type', 'application/json');
65: }
66: }
67: