1: <?php declare(strict_types=1);
2:
3: namespace Salient\Sync;
4:
5: use Salient\Contract\Core\Buildable;
6: use Salient\Contract\Core\MessageLevel as Level;
7: use Salient\Contract\Sync\SyncEntityInterface;
8: use Salient\Contract\Sync\SyncErrorInterface;
9: use Salient\Contract\Sync\SyncErrorType;
10: use Salient\Contract\Sync\SyncProviderInterface;
11: use Salient\Core\Concern\HasBuilder;
12: use Salient\Core\Concern\HasMutator;
13: use Salient\Utility\Arr;
14:
15: /**
16: * An error that occurred during a sync operation
17: *
18: * @implements Buildable<SyncErrorBuilder>
19: */
20: final class SyncError implements SyncErrorInterface, Buildable
21: {
22: /** @use HasBuilder<SyncErrorBuilder> */
23: use HasBuilder;
24: use HasMutator;
25:
26: /** @var SyncErrorType::* */
27: private int $ErrorType;
28: private string $Message;
29: /** @var list<mixed[]|object|int|float|string|bool|null> */
30: private array $Values;
31: /** @var Level::* */
32: private int $Level;
33: private ?SyncEntityInterface $Entity;
34: private ?string $EntityName;
35: private ?SyncProviderInterface $Provider;
36: private int $Count = 1;
37:
38: /**
39: * @internal
40: *
41: * @param SyncErrorType::* $errorType Error type.
42: * @param string $message `sprintf()` format string that explains the error.
43: * @param list<mixed[]|object|int|float|string|bool|null>|null $values Values applied to the message format string. Default: `[$entityName]`
44: * @param Level::* $level Error severity/message level.
45: * @param SyncEntityInterface|null $entity Entity associated with the error.
46: * @param string|null $entityName Display name of the entity associated with the error. Default: `$entity->getUri()`
47: * @param SyncProviderInterface|null $provider Sync provider associated with the error. Default: `$entity->getProvider()`
48: */
49: public function __construct(
50: int $errorType,
51: string $message,
52: ?array $values = null,
53: int $level = Level::ERROR,
54: ?SyncEntityInterface $entity = null,
55: ?string $entityName = null,
56: ?SyncProviderInterface $provider = null
57: ) {
58: $provider ??= ($entity ? $entity->getProvider() : null);
59: $entityName ??= ($entity
60: ? $entity->getUri($provider ? $provider->getStore() : null)
61: : null);
62:
63: $this->ErrorType = $errorType;
64: $this->Message = $message;
65: $this->Values = $values ?? [$entityName];
66: $this->Level = $level;
67: $this->Entity = $entity;
68: $this->EntityName = $entityName;
69: $this->Provider = $provider;
70: }
71:
72: /**
73: * @inheritDoc
74: */
75: public function getType(): int
76: {
77: return $this->ErrorType;
78: }
79:
80: /**
81: * @inheritDoc
82: */
83: public function getLevel(): int
84: {
85: return $this->Level;
86: }
87:
88: /**
89: * @inheritDoc
90: */
91: public function getCode(): string
92: {
93: return sprintf('%02d-%04d', $this->Level, $this->ErrorType);
94: }
95:
96: /**
97: * @inheritDoc
98: */
99: public function getMessage(): string
100: {
101: return sprintf($this->Message, ...Arr::toScalars($this->Values));
102: }
103:
104: /**
105: * @inheritDoc
106: */
107: public function getFormat(): string
108: {
109: return $this->Message;
110: }
111:
112: /**
113: * @inheritDoc
114: */
115: public function getValues(): array
116: {
117: return $this->Values;
118: }
119:
120: /**
121: * @inheritDoc
122: */
123: public function getProvider(): ?SyncProviderInterface
124: {
125: return $this->Provider;
126: }
127:
128: /**
129: * @inheritDoc
130: */
131: public function getEntity(): ?SyncEntityInterface
132: {
133: return $this->Entity;
134: }
135:
136: /**
137: * @inheritDoc
138: */
139: public function getEntityName(): ?string
140: {
141: return $this->EntityName;
142: }
143:
144: /**
145: * @inheritDoc
146: */
147: public function getCount(): int
148: {
149: return $this->Count;
150: }
151:
152: /**
153: * @inheritDoc
154: */
155: public function count()
156: {
157: return $this->with('Count', $this->Count + 1);
158: }
159:
160: /**
161: * @inheritDoc
162: */
163: public static function compare($a, $b): int
164: {
165: return $a->ErrorType <=> $b->ErrorType
166: ?: $a->Level <=> $b->Level
167: ?: $a->Message <=> $b->Message
168: ?: $a->Values <=> $b->Values
169: ?: $a->Provider <=> $b->Provider
170: ?: $a->Entity <=> $b->Entity
171: ?: $a->EntityName <=> $b->EntityName;
172: }
173: }
174: