1616use Salient \Contract \Sync \SyncProviderInterface ;
1717use Salient \Iterator \IterableIterator ;
1818use Salient \Sync \Exception \SyncOperationNotImplementedException ;
19+ use Salient \Sync \AbstractSyncEntity ;
1920use Salient \Sync \SyncStore ;
2021use Generator ;
2122use LogicException ;
@@ -76,13 +77,11 @@ final class SyncEntityProvider implements SyncEntityProviderInterface
7677 /**
7778 * @param class-string<TEntity> $entity
7879 * @param TProvider $provider
79- * @param SyncDefinitionInterface<TEntity,TProvider> $definition
8080 */
8181 public function __construct (
8282 ContainerInterface $ container ,
8383 string $ entity ,
8484 SyncProviderInterface $ provider ,
85- SyncDefinitionInterface $ definition ,
8685 ?SyncContextInterface $ context = null
8786 ) {
8887 if (!is_a ($ entity , SyncEntityInterface::class, true )) {
@@ -93,14 +92,62 @@ public function __construct(
9392 ));
9493 }
9594
96- $ entityProvider = SyncIntrospector::entityToProvider ($ entity );
97- if (!($ provider instanceof $ entityProvider )) {
98- throw new LogicException (get_class ($ provider ) . ' does not implement ' . $ entityProvider );
95+ if ($ context && $ context ->getProvider () !== $ provider ) {
96+ throw new LogicException (sprintf (
97+ '%s has different provider (%s, expected %s) ' ,
98+ get_class ($ context ),
99+ $ context ->getProvider ()->name (),
100+ $ provider ->name (),
101+ ));
102+ }
103+
104+ $ _entity = $ entity ;
105+ $ checked = [];
106+ do {
107+ $ entityProvider = SyncIntrospector::entityToProvider ($ entity , $ container );
108+ if (interface_exists ($ entityProvider )) {
109+ break ;
110+ }
111+ $ checked [] = $ entityProvider ;
112+ $ entityProvider = null ;
113+ $ entity = get_parent_class ($ entity );
114+ if ($ entity === false ||
115+ $ entity === AbstractSyncEntity::class ||
116+ !is_a ($ entity , SyncEntityInterface::class, true )) {
117+ break ;
118+ }
119+ } while (true );
120+
121+ if ($ entityProvider === null ) {
122+ throw new LogicException (sprintf (
123+ '%s does not have a provider interface (tried: %s) ' ,
124+ $ _entity ,
125+ implode (', ' , $ checked ),
126+ ));
127+ }
128+
129+ if (!is_a ($ provider , $ entityProvider )) {
130+ throw new LogicException (sprintf (
131+ '%s does not implement %s ' ,
132+ get_class ($ provider ),
133+ $ entityProvider
134+ ));
135+ }
136+
137+ /** @var class-string $entity */
138+ if ($ entity !== $ _entity && $ container ->getName ($ entity ) !== $ _entity ) {
139+ throw new LogicException (sprintf (
140+ '%s cannot be serviced by provider interface %s unless it is bound to the container as %s ' ,
141+ $ _entity ,
142+ $ entityProvider ,
143+ $ entity ,
144+ ));
99145 }
100146
147+ /** @var class-string<TEntity> $entity */
101148 $ this ->Entity = $ entity ;
102149 $ this ->Provider = $ provider ;
103- $ this ->Definition = $ definition ;
150+ $ this ->Definition = $ provider -> getDefinition ( $ entity ) ;
104151 $ this ->Context = $ context ?? $ provider ->getContext ($ container );
105152 $ this ->Store = $ provider ->store ();
106153 }
0 commit comments