1: <?php declare(strict_types=1);
2:
3: namespace Salient\Sync\Support;
4:
5: use Salient\Contract\Sync\Exception\FilterPolicyViolationExceptionInterface;
6: use Salient\Contract\Sync\SyncEntityInterface;
7: use Salient\Contract\Sync\SyncEntityProviderInterface;
8: use Salient\Contract\Sync\SyncEntityResolverInterface;
9:
10: /**
11: * Resolves a name to an entity by iterating over entities filtered by name
12: *
13: * Entities are retrieved every time {@see SyncEntityResolver::getByName()} is
14: * called. If a request fails because the provider is unable to filter entities
15: * by name, a fallback request for every entity is made.
16: *
17: * @api
18: *
19: * @template TEntity of SyncEntityInterface
20: *
21: * @implements SyncEntityResolverInterface<TEntity>
22: */
23: final class SyncEntityResolver implements SyncEntityResolverInterface
24: {
25: /** @var SyncEntityProviderInterface<TEntity> */
26: private SyncEntityProviderInterface $EntityProvider;
27: private string $NameProperty;
28:
29: /**
30: * @api
31: *
32: * @param SyncEntityProviderInterface<TEntity> $entityProvider
33: */
34: public function __construct(
35: SyncEntityProviderInterface $entityProvider,
36: string $nameProperty
37: ) {
38: $this->EntityProvider = $entityProvider;
39: $this->NameProperty = $nameProperty;
40: }
41:
42: /**
43: * @inheritDoc
44: */
45: public function getByName(string $name, ?float &$uncertainty = null): ?SyncEntityInterface
46: {
47: try {
48: $entity = $this->doGetByName($name, [$this->NameProperty => $name]);
49: } catch (FilterPolicyViolationExceptionInterface $ex) {
50: $entity = $this->doGetByName($name);
51: }
52:
53: $uncertainty = $entity ? 0.0 : null;
54: return $entity;
55: }
56:
57: /**
58: * @param mixed ...$args
59: * @return TEntity|null
60: */
61: private function doGetByName(string $name, ...$args): ?SyncEntityInterface
62: {
63: return $this
64: ->EntityProvider
65: ->getList(...$args)
66: ->getFirstWith($this->NameProperty, $name, true);
67: }
68: }
69: