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