1: <?php
2:
3: namespace LaravelUi5\Core\Attributes;
4:
5: use Attribute;
6: use Illuminate\Database\Eloquent\Model;
7:
8: /**
9: * Declares the primary *semantic object* represented by a Ui5Module.
10: *
11: * A semantic object is the logical entry point of a module — describing which
12: * business entity this module "owns" (e.g. BusinessPartner, Project, Invoice)
13: * and how other modules or the UI can reach it via named navigation intents.
14: *
15: * Each Ui5Module must declare **exactly one** SemanticObject.
16: *
17: * ### Purpose
18: * This attribute enables:
19: * - automatic cross-module linking via {@see SemanticLink}
20: * - semantic intent navigation in the UI
21: * - backend reflection and registry consistency
22: *
23: * ### Example
24: * ```php
25: * use LaravelUi5\Core\Attributes\SemanticObject;
26: *
27: * #[SemanticObject(
28: * model: \Pragmatiqu\Partners\Models\Partner::class,
29: * name: 'BusinessPartner',
30: * routes: [
31: * 'detail' => [
32: * 'uri' => '/Detail/{id}',
33: * 'label' => 'Partner Details',
34: * 'icon' => 'sap-icon://person-placeholder',
35: * ],
36: * 'roles' => [
37: * 'uri' => '/Roles?partner_id={id}',
38: * 'label' => 'Assigned Roles',
39: * 'icon' => 'sap-icon://role',
40: * ],
41: * ],
42: * icon: 'sap-icon://group'
43: * )]
44: * class PartnersModule extends Ui5Module {}
45: * ```
46: *
47: * ### Parameters
48: * @param string $model Fully qualified Eloquent model class that represents
49: * the business entity. Must exist and be autoloadable.
50: * @param string $name Canonical semantic name used for system integration.
51: * English only, PascalCase, unique system-wide.
52: * @param array $routes Named navigation intents. Each must define at least:
53: * - `uri` (string URI template, may contain {id})
54: * - `label` (human label for the UI)
55: * Optional: `icon` (UI5 icon string)
56: * @param string|null $icon Optional module icon for UI display.
57: *
58: * ### Validation rules
59: * - Exactly one SemanticObject per Ui5Module.
60: * - `$routes` must contain at least one intent.
61: * - `$name` must be unique across all modules.
62: */
63: #[Attribute(Attribute::TARGET_CLASS)]
64: class SemanticObject
65: {
66: /**
67: * @param class-string<Model> $model Fully qualified model class (system key).
68: * @param string $name Human-readable system name (English only).
69: * @param array $routes Named route intents (must contain at least one).
70: * @param string|null $icon Optional UI5 icon for UI representation.
71: */
72: public function __construct(
73: public string $model,
74: public string $name,
75: public array $routes,
76: public ?string $icon = null,
77: )
78: {
79: }
80: }
81: