8
8
use App \Field \Domain \Enum \FieldPlace ;
9
9
use App \Field \Domain \Exception \FieldEntityNotFoundException ;
10
10
use App \Field \Domain \Exception \FieldInvalidNameException ;
11
+ use App \Field \Domain \Exception \FieldParentWikidataIdNotFoundException ;
11
12
use App \Field \Domain \Exception \FieldUnicityViolationException ;
12
13
use App \Field \Domain \Model \Field ;
13
14
use App \Field \Domain \Repository \FieldRepositoryInterface ;
@@ -48,15 +49,13 @@ public function upsertFields(Place|Community $entity, array $fieldPayloads): voi
48
49
Community::class => FieldCommunity::tryFrom ($ fieldPayload ->name ),
49
50
default => null ,
50
51
};
51
- $ aliases = match ($ entity ::class) {
52
- Place::class => FieldPlace::ALIASES ,
53
- Community::class => FieldCommunity::ALIASES ,
54
- default => null ,
55
- };
52
+
56
53
if (null === $ enumValue ) {
57
54
throw new FieldInvalidNameException ($ fieldPayload ->name );
58
55
}
59
56
57
+ $ this ->maybeTransformAlias ($ entity , $ enumValue , $ fieldPayload );
58
+
60
59
$ field = $ this ->getOrCreate (
61
60
$ entity ,
62
61
$ enumValue ,
@@ -69,9 +68,6 @@ public function upsertFields(Place|Community $entity, array $fieldPayloads): voi
69
68
$ field ->place = $ entity ;
70
69
}
71
70
72
- if (in_array ($ enumValue ->name , array_keys ($ aliases ))) {
73
- $ fieldPayload ->name = $ aliases [$ enumValue ->name ]->value ;
74
- }
75
71
$ field ->name = $ fieldPayload ->name ;
76
72
$ field ->value = $ value ;
77
73
$ field ->engine = $ fieldPayload ->engine ;
@@ -83,8 +79,7 @@ public function upsertFields(Place|Community $entity, array $fieldPayloads): voi
83
79
// Unique constraints validation (TODO use custom Assert instead)
84
80
if (null !== $ field ->value
85
81
&& in_array ($ field ->name , Field::UNIQUE_CONSTRAINTS , true )
86
- && (null !== $ attachedToId = $ this ->fieldRepo ->exists ($ entity ->id , $ enumValue , $ field ->value ))
87
- && $ attachedToId !== $ entity ->id ->toString ()
82
+ && $ this ->fieldRepo ->existOusideOf ($ entity ->id , $ enumValue , $ field ->value )
88
83
) {
89
84
throw new FieldUnicityViolationException ($ field ->name , $ field ->value );
90
85
}
@@ -163,14 +158,9 @@ private function maybeTransformEntities(FieldCommunity|FieldPlace $nameEnum, mix
163
158
return $ instances ->toArray ();
164
159
} else {
165
160
$ instance = null ;
166
- if ($ nameEnum ->name === FieldCommunity::PARENT_WIKIDATA_ID ->name ) {
167
- assert (is_int ($ value ));
168
- $ instance = $ repo ->withWikidataId ($ value )->asCollection ()[0 ];
169
- } else {
170
- // That's an object
171
- assert (is_string ($ value ));
172
- $ instance = $ repo ->ofId (Uuid::fromString ($ value ));
173
- }
161
+ // That's an object
162
+ assert (is_string ($ value ));
163
+ $ instance = $ repo ->ofId (Uuid::fromString ($ value ));
174
164
175
165
if (!$ instance ) {
176
166
throw new FieldEntityNotFoundException ($ value );
@@ -179,4 +169,52 @@ private function maybeTransformEntities(FieldCommunity|FieldPlace $nameEnum, mix
179
169
return $ instance ;
180
170
}
181
171
}
172
+
173
+ private function maybeTransformAlias (Place |Community $ entity , FieldCommunity |FieldPlace &$ enumValue , Field &$ fieldPayload ): void
174
+ {
175
+ $ aliases = match ($ entity ::class) {
176
+ Place::class => FieldPlace::ALIASES ,
177
+ Community::class => FieldCommunity::ALIASES ,
178
+ default => null ,
179
+ };
180
+
181
+ if (!in_array ($ enumValue ->name , array_keys ($ aliases ))) {
182
+ return ;
183
+ }
184
+
185
+ $ enumValue = $ aliases [$ enumValue ->name ];
186
+ $ fieldPayload ->value = match ($ fieldPayload ->name ) {
187
+ FieldCommunity::PARENT_WIKIDATA_ID ->value => $ this ->wikidataIdToCommunityId ($ fieldPayload ->value ),
188
+ FieldPlace::PARENT_WIKIDATA_IDS ->value => $ this ->wikidataIdsToCommunityIds ($ fieldPayload ->value ),
189
+ default => null ,
190
+ };
191
+ $ fieldPayload ->name = $ enumValue ->value ;
192
+ }
193
+
194
+ private function wikidataIdToCommunityId (int $ wikidataId ): string
195
+ {
196
+ $ fields = $ this ->fieldRepo ->getNameValueFields (FieldCommunity::WIKIDATA_ID , $ wikidataId );
197
+ if (0 === count ($ fields )) {
198
+ throw new FieldParentWikidataIdNotFoundException ([$ wikidataId ]);
199
+ }
200
+
201
+ return $ fields [0 ]->community ->id ->toString () ?? $ fields [0 ]->place ->id ->toString ();
202
+ }
203
+
204
+ /**
205
+ * @param int[] $wikidataIds
206
+ *
207
+ * @return string[]
208
+ */
209
+ private function wikidataIdsToCommunityIds (array $ wikidataIds ): array
210
+ {
211
+ $ fields = $ this ->fieldRepo ->getNameValueFields (FieldCommunity::WIKIDATA_ID , $ wikidataIds );
212
+ $ foundWikidataIds = array_map (fn (Field $ field ) => $ field ->getValue (), $ fields );
213
+ $ missingWikidataIds = array_diff ($ wikidataIds , $ foundWikidataIds );
214
+ if (count ($ fields ) !== count ($ wikidataIds )) {
215
+ throw new FieldParentWikidataIdNotFoundException ($ missingWikidataIds );
216
+ }
217
+
218
+ return array_map (fn (Field $ field ) => $ field ->community ->id ->toString () ?? $ field ->place ->id ->toString (), $ fields );
219
+ }
182
220
}
0 commit comments