1: <?php declare(strict_types=1);
2:
3: namespace Salient\Sync\Db;
4:
5: use Salient\Contract\Core\Pipeline\PipelineInterface;
6: use Salient\Contract\Core\ArrayMapperFlag;
7: use Salient\Contract\Core\Buildable;
8: use Salient\Contract\Core\ListConformity;
9: use Salient\Contract\Sync\FilterPolicy;
10: use Salient\Contract\Sync\SyncContextInterface;
11: use Salient\Contract\Sync\SyncEntityInterface;
12: use Salient\Contract\Sync\SyncEntitySource;
13: use Salient\Contract\Sync\SyncOperation as OP;
14: use Salient\Core\Concern\HasBuilder;
15: use Salient\Sync\Support\SyncPipelineArgument;
16: use Salient\Sync\AbstractSyncDefinition;
17: use Closure;
18: use LogicException;
19:
20: /**
21: * Generates closures that use a DbSyncProvider to perform sync operations on an
22: * entity
23: *
24: * @template TEntity of SyncEntityInterface
25: * @template TProvider of DbSyncProvider
26: *
27: * @phpstan-type OverrideClosure (Closure(static, OP::*, SyncContextInterface, int|string|null, mixed...): TEntity)|(Closure(static, OP::*, SyncContextInterface, mixed...): iterable<TEntity>)|(Closure(static, OP::*, SyncContextInterface, TEntity, mixed...): TEntity)|(Closure(static, OP::*, SyncContextInterface, iterable<TEntity>, mixed...): iterable<TEntity>)
28: *
29: * @property-read string|null $Table
30: *
31: * @extends AbstractSyncDefinition<TEntity,TProvider>
32: * @implements Buildable<DbSyncDefinitionBuilder<TEntity,TProvider>>
33: */
34: final class DbSyncDefinition extends AbstractSyncDefinition implements Buildable
35: {
36: /** @use HasBuilder<DbSyncDefinitionBuilder<TEntity,TProvider>> */
37: use HasBuilder;
38:
39: /** @var string|null */
40: protected $Table;
41:
42: /**
43: * @internal
44: *
45: * @param class-string<TEntity> $entity
46: * @param TProvider $provider
47: * @param array<OP::*> $operations
48: * @param ListConformity::* $conformity
49: * @param FilterPolicy::*|null $filterPolicy
50: * @param array<int-mask-of<OP::*>,Closure(DbSyncDefinition<TEntity,TProvider>, OP::*, SyncContextInterface, mixed...): (iterable<TEntity>|TEntity)> $overrides
51: * @phpstan-param array<int-mask-of<OP::*>,OverrideClosure> $overrides
52: * @param array<array-key,array-key|array-key[]>|null $keyMap
53: * @param int-mask-of<ArrayMapperFlag::*> $keyMapFlags
54: * @param PipelineInterface<mixed[],TEntity,SyncPipelineArgument>|null $pipelineFromBackend
55: * @param PipelineInterface<TEntity,mixed[],SyncPipelineArgument>|null $pipelineToBackend
56: * @param SyncEntitySource::*|null $returnEntitiesFrom
57: */
58: public function __construct(
59: string $entity,
60: DbSyncProvider $provider,
61: array $operations = [],
62: ?string $table = null,
63: $conformity = ListConformity::PARTIAL,
64: ?int $filterPolicy = null,
65: array $overrides = [],
66: ?array $keyMap = null,
67: int $keyMapFlags = ArrayMapperFlag::ADD_UNMAPPED,
68: ?PipelineInterface $pipelineFromBackend = null,
69: ?PipelineInterface $pipelineToBackend = null,
70: bool $readFromList = false,
71: ?int $returnEntitiesFrom = null
72: ) {
73: parent::__construct(
74: $entity,
75: $provider,
76: $operations,
77: $conformity,
78: $filterPolicy,
79: $overrides,
80: $keyMap,
81: $keyMapFlags,
82: $pipelineFromBackend,
83: $pipelineToBackend,
84: $readFromList,
85: $returnEntitiesFrom
86: );
87:
88: $this->Table = $table;
89: }
90:
91: /**
92: * @inheritDoc
93: */
94: protected function getClosure($operation): ?Closure
95: {
96: // Return null if no table name has been provided
97: if ($this->Table === null) {
98: return null;
99: }
100:
101: switch ($operation) {
102: case OP::CREATE:
103: case OP::READ:
104: case OP::UPDATE:
105: case OP::DELETE:
106: case OP::CREATE_LIST:
107: case OP::READ_LIST:
108: case OP::UPDATE_LIST:
109: case OP::DELETE_LIST:
110: $closure = null;
111: break;
112:
113: default:
114: throw new LogicException("Invalid SyncOperation: $operation");
115: }
116:
117: return $closure;
118: }
119:
120: public static function getReadableProperties(): array
121: {
122: return [
123: ...parent::getReadableProperties(),
124: 'Table',
125: ];
126: }
127: }
128: