|
8 | 8 | use Salient\Contract\Sync\SyncProviderInterface; |
9 | 9 | use Salient\Contract\Sync\SyncStoreInterface; |
10 | 10 | use Salient\Core\Facade\Sync; |
| 11 | +use Salient\Sync\Reflection\ReflectionSyncProvider; |
11 | 12 | use Salient\Utility\AbstractUtility; |
12 | 13 | use Salient\Utility\Arr; |
13 | 14 | use Salient\Utility\Get; |
14 | 15 | use Salient\Utility\Regex; |
| 16 | +use LogicException; |
| 17 | +use ReflectionClass; |
15 | 18 |
|
16 | 19 | final class SyncUtil extends AbstractUtility |
17 | 20 | { |
@@ -51,6 +54,51 @@ public static function isWriteOperation(int $operation): bool |
51 | 54 | ][$operation] ?? false; |
52 | 55 | } |
53 | 56 |
|
| 57 | + /** |
| 58 | + * With a sync entity type and any non-abstract parents bound to it in a |
| 59 | + * service container, get the first that is serviced by a provider |
| 60 | + * |
| 61 | + * @template T of SyncEntityInterface |
| 62 | + * |
| 63 | + * @param class-string<T> $entityType |
| 64 | + * @return class-string<T> |
| 65 | + * @throws LogicException if the provider does not service the entity type. |
| 66 | + */ |
| 67 | + public static function getServicedEntityType( |
| 68 | + string $entityType, |
| 69 | + SyncProviderInterface $provider, |
| 70 | + ContainerInterface $container |
| 71 | + ): string { |
| 72 | + $provider = new ReflectionSyncProvider($provider); |
| 73 | + if ($provider->isSyncEntityProvider($entityType)) { |
| 74 | + return $entityType; |
| 75 | + } |
| 76 | + |
| 77 | + $entity = new ReflectionClass($entityType); |
| 78 | + do { |
| 79 | + $entity = $entity->getParentClass(); |
| 80 | + if ( |
| 81 | + !$entity |
| 82 | + || $entity->isAbstract() |
| 83 | + ) { |
| 84 | + throw new LogicException(sprintf( |
| 85 | + '%s does not service %s', |
| 86 | + $provider->name, |
| 87 | + $entityType, |
| 88 | + )); |
| 89 | + } |
| 90 | + if ( |
| 91 | + is_a($container->getName($entity->name), $entityType, true) |
| 92 | + && $provider->isSyncEntityProvider($entity) |
| 93 | + ) { |
| 94 | + break; |
| 95 | + } |
| 96 | + } while (true); |
| 97 | + |
| 98 | + /** @var class-string<T> */ |
| 99 | + return $entity->name; |
| 100 | + } |
| 101 | + |
54 | 102 | /** |
55 | 103 | * Get the name of a sync entity type's provider interface |
56 | 104 | * |
|
0 commit comments