1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace LaravelUi5\OData\Service\Contracts;
6:
7: use InvalidArgumentException;
8: use LaravelUi5\OData\Edm\Contracts\Container\EntitySetInterface;
9: use LaravelUi5\OData\Edm\Contracts\Container\FunctionImportInterface;
10: use LaravelUi5\OData\Edm\Contracts\Container\SingletonInterface;
11: use LaravelUi5\OData\Edm\Contracts\EdmxInterface;
12: use RuntimeException;
13:
14: /**
15: * Mutable accumulator that binds resolvers to a frozen EdmxInterface and
16: * produces a RuntimeSchemaInterface.
17: *
18: * This is Stage 2 of the two-stage builder. It wraps an already-built
19: * EdmxInterface (from either EdmBuilderInterface::build() or EdmxLoader) and
20: * accepts resolver registrations for each entity set and function import.
21: *
22: * ODataService subclasses override bindResolvers() to populate this builder.
23: * The method receives the builder already wrapping the correct EdmxInterface,
24: * so callers can retrieve canonical entity-set objects via getEdmx() and pass
25: * them as object references to bindEntitySet().
26: *
27: * Typical usage:
28: *
29: * protected function bindResolvers(RuntimeSchemaBuilderInterface $builder): RuntimeSchemaBuilderInterface
30: * {
31: * $c = $builder->getEdmx()->getEntityContainer();
32: * return $builder
33: * ->bindEntitySet($c->getEntitySet('Partners'), new EloquentEntitySetResolver(Partner::class));
34: * }
35: *
36: * @see EdmBuilderInterface Stage 1 — builds the pure EdmxInterface
37: * @see RuntimeSchemaInterface The frozen result produced by build()
38: */
39: interface RuntimeSchemaBuilderInterface
40: {
41: /**
42: * The frozen Edm document this builder was constructed with.
43: *
44: * Use this to retrieve canonical EntitySetInterface object references for
45: * passing to bindEntitySet(). The returned objects have stable identity for
46: * the lifetime of this builder.
47: */
48: public function getEdmx(): EdmxInterface;
49:
50: /**
51: * Binds a resolver to a specific entity set.
52: *
53: * The $set parameter must be the exact EntitySetInterface instance from
54: * getEdmx() — binding uses object identity (spl_object_id) as the key.
55: * Retrieve the canonical instance via:
56: * $builder->getEdmx()->getEntityContainer()->getEntitySet('Name')
57: *
58: * @throws InvalidArgumentException if $set is not part of this builder's EdmxInterface
59: */
60: public function bindEntitySet(EntitySetInterface $set, EntitySetResolverInterface $resolver): static;
61:
62: /**
63: * Binds a resolver to a specific function import.
64: *
65: * The $import parameter must be the exact FunctionImportInterface instance
66: * from getEdmx(). Retrieve it via:
67: * $builder->getEdmx()->getEntityContainer()->getFunctionImport('Name')
68: *
69: * @throws InvalidArgumentException if $import is not part of this builder's EdmxInterface
70: */
71: public function bindFunctionImport(FunctionImportInterface $import, FunctionResolverInterface $resolver): static;
72:
73: /**
74: * Binds a resolver to a specific singleton.
75: *
76: * @throws InvalidArgumentException if $singleton is not part of this builder's EdmxInterface
77: */
78: public function bindSingleton(SingletonInterface $singleton, SingletonResolverInterface $resolver): static;
79:
80: /**
81: * Freeze the accumulated resolver bindings into a RuntimeSchemaInterface.
82: *
83: * @throws RuntimeException if any entity set in the EdmxInterface has no resolver bound
84: */
85: public function build(): RuntimeSchemaInterface;
86: }
87: