@@ -99,7 +99,6 @@ private function getClassMetadata(ReflectionClass $reflectionClass): ClassMetada
9999 $ metadata = new ClassMetadata (
100100 $ reflectionClass ,
101101 $ this ->getPropertyMetadataList ($ reflectionClass ),
102- $ this ->getSubjectIdField ($ reflectionClass ),
103102 $ this ->getPostHydrateCallbacks ($ reflectionClass ),
104103 $ this ->getPreExtractCallbacks ($ reflectionClass ),
105104 $ this ->getLazy ($ reflectionClass ),
@@ -156,6 +155,7 @@ private function getPropertyMetadataList(ReflectionClass $reflectionClass): arra
156155 $ reflectionProperty ,
157156 $ fieldName ,
158157 $ this ->getNormalizer ($ reflectionProperty ),
158+ $ this ->getSubjectId ($ reflectionProperty ),
159159 ...$ this ->getPersonalData ($ reflectionProperty ),
160160 );
161161 }
@@ -270,82 +270,73 @@ private function mergeMetadata(ClassMetadata $parent, ClassMetadata $child): Cla
270270 $ properties [$ property ->fieldName ()] = $ property ;
271271 }
272272
273- $ parentDataSubjectIdField = $ parent ->dataSubjectIdField ();
274- $ childDataSubjectIdField = $ child ->dataSubjectIdField ();
275-
276- if ($ parentDataSubjectIdField !== null && $ childDataSubjectIdField !== null ) {
277- $ parentProperty = $ parent ->propertyForField ($ parentDataSubjectIdField );
278- $ childProperty = $ child ->propertyForField ($ childDataSubjectIdField );
279-
280- throw new MultipleDataSubjectId ($ parentProperty ->propertyName (), $ childProperty ->propertyName ());
281- }
282-
283- return new ClassMetadata (
273+ $ mergedClassMetadata = new ClassMetadata (
284274 $ parent ->reflection (),
285275 array_values ($ properties ),
286- $ parentDataSubjectIdField ?? $ childDataSubjectIdField ,
287276 array_merge ($ parent ->postHydrateCallbacks (), $ child ->postHydrateCallbacks ()),
288277 array_merge ($ parent ->preExtractCallbacks (), $ child ->preExtractCallbacks ()),
289278 $ child ->lazy () ?? $ parent ->lazy (),
290279 );
291- }
292280
293- /** @param ReflectionClass<object> $reflectionClass */
294- private function getSubjectIdField (ReflectionClass $ reflectionClass ): string |null
295- {
296- $ property = null ;
281+ $ this ->validate ($ mergedClassMetadata );
297282
298- foreach ($ reflectionClass ->getProperties () as $ reflectionProperty ) {
299- $ attributeReflectionList = $ reflectionProperty ->getAttributes (DataSubjectId::class);
300-
301- if (!$ attributeReflectionList ) {
302- continue ;
303- }
304-
305- if ($ property !== null ) {
306- throw new MultipleDataSubjectId ($ property ->getName (), $ reflectionProperty ->getName ());
307- }
283+ return $ mergedClassMetadata ;
284+ }
308285
309- $ property = $ reflectionProperty ;
310- }
286+ private function getSubjectId (ReflectionProperty $ reflectionProperty ): string |null
287+ {
288+ $ attributeReflectionList = $ reflectionProperty ->getAttributes (DataSubjectId::class);
311289
312- if ($ property === null ) {
290+ if (! $ attributeReflectionList ) {
313291 return null ;
314292 }
315293
316- return $ this -> getFieldName ( $ property ) ;
294+ return $ attributeReflectionList [ 0 ]-> newInstance ()-> identifier ;
317295 }
318296
319- /** @return array{bool , mixed, (callable(string, mixed):mixed)|null} */
297+ /** @return array{string|null , mixed, (callable(string, mixed):mixed)|null} */
320298 private function getPersonalData (ReflectionProperty $ reflectionProperty ): array
321299 {
322300 $ attributeReflectionList = $ reflectionProperty ->getAttributes (PersonalData::class);
323301
324302 if ($ attributeReflectionList === []) {
325- return [false , null ];
303+ return [null , null , null ];
326304 }
327305
328306 $ attribute = $ attributeReflectionList [0 ]->newInstance ();
329307
330- return [true , $ attribute ->fallback , $ attribute ->fallbackCallable ];
308+ return [$ attribute -> identifier , $ attribute ->fallback , $ attribute ->fallbackCallable ];
331309 }
332310
333311 private function validate (ClassMetadata $ metadata ): void
334312 {
335- $ hasPersonalData = false ;
313+ $ subjectIds = [] ;
336314
337315 foreach ($ metadata ->properties () as $ property ) {
338- if ($ property ->isPersonalData ()) {
339- $ hasPersonalData = true ;
316+ if ($ property ->isPersonalData () && $ property -> isSubjectId () ) {
317+ throw new SubjectIdAndPersonalDataConflict ( $ metadata -> className (), $ property -> propertyName ()) ;
340318 }
341319
342- if ($ property ->isPersonalData () && $ metadata ->dataSubjectIdField () === $ property ->fieldName ()) {
343- throw new SubjectIdAndPersonalDataConflict ($ metadata ->className (), $ property ->propertyName ());
320+ if ($ property ->isPersonalData () && !$ metadata ->hasSubjectIdIdentifier ($ property ->personalDataIdentifier ())) {
321+ throw new MissingDataSubjectId ($ metadata ->className ());
322+ }
323+
324+ if (!$ property ->isSubjectId ()) {
325+ continue ;
326+ }
327+
328+ $ subjectIdIdentifier = $ property ->subjectIdIdentifier ();
329+
330+ if (array_key_exists ($ subjectIdIdentifier , $ subjectIds )) {
331+ throw new DuplicateSubjectIdIdentifier (
332+ $ metadata ->className (),
333+ $ subjectIds [$ subjectIdIdentifier ],
334+ $ property ->propertyName (),
335+ $ subjectIdIdentifier ,
336+ );
344337 }
345- }
346338
347- if ($ hasPersonalData && $ metadata ->dataSubjectIdField () === null ) {
348- throw new MissingDataSubjectId ($ metadata ->className ());
339+ $ subjectIds [$ subjectIdIdentifier ] = $ property ->propertyName ();
349340 }
350341 }
351342
0 commit comments