1: <?php declare(strict_types=1);
2:
3: namespace Salient\Sync;
4:
5: use Salient\Contract\Container\ContainerInterface;
6: use Salient\Contract\Sync\SyncEntityInterface;
7: use Salient\Contract\Sync\SyncOperation;
8: use Salient\Contract\Sync\SyncProviderInterface;
9: use Salient\Contract\Sync\SyncStoreInterface;
10: use Salient\Core\Facade\Sync;
11: use Salient\Utility\AbstractUtility;
12: use Salient\Utility\Arr;
13: use Salient\Utility\Get;
14: use Salient\Utility\Regex;
15:
16: final class SyncUtil extends AbstractUtility
17: {
18: /**
19: * Check if a sync operation is CREATE_LIST, READ_LIST, UPDATE_LIST or
20: * DELETE_LIST
21: *
22: * @param SyncOperation::* $operation
23: * @return ($operation is SyncOperation::*_LIST ? true : false)
24: */
25: public static function isListOperation(int $operation): bool
26: {
27: return [
28: SyncOperation::CREATE_LIST => true,
29: SyncOperation::READ_LIST => true,
30: SyncOperation::UPDATE_LIST => true,
31: SyncOperation::DELETE_LIST => true,
32: ][$operation] ?? false;
33: }
34:
35: /**
36: * Check if a sync operation is CREATE, UPDATE, DELETE, CREATE_LIST,
37: * UPDATE_LIST or DELETE_LIST
38: *
39: * @param SyncOperation::* $operation
40: * @return ($operation is SyncOperation::READ* ? false : true)
41: */
42: public static function isWriteOperation(int $operation): bool
43: {
44: return [
45: SyncOperation::CREATE => true,
46: SyncOperation::UPDATE => true,
47: SyncOperation::DELETE => true,
48: SyncOperation::CREATE_LIST => true,
49: SyncOperation::UPDATE_LIST => true,
50: SyncOperation::DELETE_LIST => true,
51: ][$operation] ?? false;
52: }
53:
54: /**
55: * Get the name of a sync entity type's provider interface
56: *
57: * @param class-string<SyncEntityInterface> $entityType
58: * @return class-string<SyncProviderInterface>
59: */
60: public static function getEntityTypeProvider(
61: string $entityType,
62: ?SyncStoreInterface $store = null
63: ): string {
64: if ($store) {
65: $helper = $store->getNamespaceHelper($entityType);
66: if ($helper) {
67: return $helper->getEntityTypeProvider($entityType);
68: }
69: }
70:
71: /** @var class-string<SyncProviderInterface> */
72: return Arr::implode('\\', [
73: Get::namespace($entityType),
74: 'Provider',
75: Get::basename($entityType) . 'Provider',
76: ]);
77: }
78:
79: /**
80: * Get the names of sync entity types serviced by a provider interface
81: *
82: * @param class-string<SyncProviderInterface> $provider
83: * @return array<class-string<SyncEntityInterface>>
84: */
85: public static function getProviderEntityTypes(
86: string $provider,
87: ?SyncStoreInterface $store = null
88: ): array {
89: if ($store) {
90: $helper = $store->getNamespaceHelper($provider);
91: if ($helper) {
92: return $helper->getProviderEntityTypes($provider);
93: }
94: }
95:
96: if (Regex::match(
97: '/^\\\\?(?<namespace>(?:[^\\\\]++\\\\)*)Provider\\\\(?<class>[^\\\\]+)Provider$/',
98: $provider,
99: $matches,
100: )) {
101: /** @var array<class-string<SyncEntityInterface>> */
102: return [$matches['namespace'] . $matches['class']];
103: }
104:
105: return [];
106: }
107:
108: /**
109: * Get the canonical URI of a sync entity type
110: *
111: * @param class-string<SyncEntityInterface> $entityType
112: */
113: public static function getEntityTypeUri(
114: string $entityType,
115: bool $compact = true,
116: ?SyncStoreInterface $store = null
117: ): string {
118: if ($store) {
119: return $store->getEntityTypeUri($entityType, $compact);
120: }
121: return '/' . str_replace('\\', '/', ltrim($entityType, '\\'));
122: }
123:
124: /**
125: * Get an entity store, creating one if necessary
126: *
127: * If a container with a shared {@see SyncStoreInterface} instance is given,
128: * it is returned. Otherwise, {@see Sync::getInstance()} is returned if
129: * loaded, or a new {@see SyncStore} instance is created.
130: */
131: public static function getStore(?ContainerInterface $container = null): SyncStoreInterface
132: {
133: if ($container && $container->hasInstance(SyncStoreInterface::class)) {
134: return $container->get(SyncStoreInterface::class);
135: }
136: if (Sync::isLoaded()) {
137: return Sync::getInstance();
138: }
139: return new SyncStore();
140: }
141: }
142: