1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace LaravelUi5\OData\Service\Builder;
6:
7: use LaravelUi5\OData\Edm\Contracts\Container\EntitySetInterface;
8: use LaravelUi5\OData\Edm\Contracts\EdmxInterface;
9: use LaravelUi5\OData\Service\Contracts\EntitySetResolverInterface;
10: use LaravelUi5\OData\Service\Contracts\EntitySetSourceInterface;
11: use LaravelUi5\OData\Service\Contracts\ResolverBindingInterface;
12: use LaravelUi5\OData\Service\Resolver\CustomBinding;
13: use LaravelUi5\OData\Service\Resolver\EloquentBinding;
14: use LaravelUi5\OData\Service\Resolver\ResolverMap;
15: use LaravelUi5\OData\Service\Resolver\SqlBinding;
16: use LaravelUi5\OData\Service\Resolver\SqlSourceBinding;
17:
18: /**
19: * Fluent builder for constructing a ResolverMap.
20: *
21: * Used in ODataService::registerBindings() to declare entity set bindings.
22: * Accepts EntitySetInterface as keys (type-safe), stores by name for
23: * serialization.
24: */
25: final class ResolverMapBuilder
26: {
27: /** @var array<string, ResolverBindingInterface> entitySetName => binding */
28: private array $bindings = [];
29:
30: public function __construct(private readonly EdmxInterface $edmx) {}
31:
32: public function getEdmx(): EdmxInterface
33: {
34: return $this->edmx;
35: }
36:
37: /**
38: * Bind an entity set to an Eloquent model class.
39: *
40: * @param class-string<\Illuminate\Database\Eloquent\Model> $modelClass
41: */
42: public function eloquent(EntitySetInterface $set, string $modelClass): static
43: {
44: $this->bindings[$set->getName()] = new EloquentBinding($modelClass);
45: return $this;
46: }
47:
48: /**
49: * Bind an entity set to a raw database table or view.
50: */
51: public function sql(EntitySetInterface $set, string $table, ?string $connection = null): static
52: {
53: $this->bindings[$set->getName()] = new SqlBinding($table, $connection);
54: return $this;
55: }
56:
57: /**
58: * Bind an entity set to an EntitySetSourceInterface implementation.
59: *
60: * The source class is resolved from the Laravel container at runtime,
61: * so dependencies (tenant context, user, etc.) are injected.
62: *
63: * @param class-string<EntitySetSourceInterface> $sourceClass
64: */
65: public function sqlSource(EntitySetInterface $set, string $sourceClass): static
66: {
67: $this->bindings[$set->getName()] = new SqlSourceBinding($sourceClass);
68: return $this;
69: }
70:
71: /**
72: * Bind an entity set to a custom EntitySetResolverInterface implementation.
73: *
74: * The resolver class is resolved from the Laravel container at runtime,
75: * so dependencies are injected. Use this for entity sets that don't map
76: * to a single Eloquent model or SQL table.
77: *
78: * @param class-string<EntitySetResolverInterface> $resolverClass
79: */
80: public function custom(EntitySetInterface $set, string $resolverClass): static
81: {
82: $this->bindings[$set->getName()] = new CustomBinding($resolverClass);
83: return $this;
84: }
85:
86: /**
87: * Build the frozen ResolverMap from collected bindings.
88: */
89: public function build(): ResolverMap
90: {
91: return new ResolverMap($this->bindings);
92: }
93:
94: /**
95: * @return array<string, ResolverBindingInterface>
96: */
97: public function getBindings(): array
98: {
99: return $this->bindings;
100: }
101: }
102: