17
17
use ApiPlatform \Metadata \Operation ;
18
18
use ApiPlatform \Metadata \Util \ClassInfoTrait ;
19
19
use ApiPlatform \State \ProcessorInterface ;
20
- use Doctrine \ODM \MongoDB \Mapping \ClassMetadata ;
21
- use Doctrine \ORM \Mapping \ClassMetadataInfo ;
22
20
use Doctrine \Persistence \ManagerRegistry ;
23
21
use Doctrine \Persistence \ObjectManager as DoctrineObjectManager ;
24
22
@@ -50,48 +48,48 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
50
48
// PUT: reset the existing object managed by Doctrine and merge data sent by the user in it
51
49
// This custom logic is needed because EntityManager::merge() has been deprecated and UPSERT isn't supported:
52
50
// https://github.com/doctrine/orm/issues/8461#issuecomment-1250233555
53
- if ($ operation instanceof HttpOperation && HttpOperation:: METHOD_PUT === $ operation ->getMethod () && ($ operation ->getExtraProperties ()['standard_put ' ] ?? false )) {
51
+ if ($ operation instanceof HttpOperation && ' PUT ' === $ operation ->getMethod () && ($ operation ->getExtraProperties ()['standard_put ' ] ?? false )) {
54
52
\assert (method_exists ($ manager , 'getReference ' ));
55
- // TODO: the call to getReference is most likely to fail with complex identifiers
56
53
$ newData = $ data ;
57
- if (isset ($ context ['previous_data ' ])) {
58
- $ newData = 1 === \count ($ uriVariables ) ? $ manager ->getReference ($ class , current ($ uriVariables )) : clone $ context ['previous_data ' ];
59
- }
60
-
61
54
$ identifiers = array_reverse ($ uriVariables );
62
55
$ links = $ this ->getLinks ($ class , $ operation , $ context );
63
56
$ reflectionProperties = $ this ->getReflectionProperties ($ data );
64
57
65
- if (!isset ($ context ['previous_data ' ])) {
66
- foreach (array_reverse ($ links ) as $ link ) {
67
- if ($ link ->getExpandedValue () || !$ link ->getFromClass ()) {
58
+ // TODO: the call to getReference is most likely to fail with complex identifiers
59
+ if ($ previousData = $ context ['previous_data ' ]) {
60
+ $ classMetadata = $ manager ->getClassMetadata ($ class );
61
+ $ identifiers = $ classMetadata ->getIdentifierValues ($ previousData );
62
+ $ newData = 1 === \count ($ identifiers ) ? $ manager ->getReference ($ class , current ($ identifiers )) : clone $ previousData ;
63
+
64
+ foreach ($ reflectionProperties as $ propertyName => $ reflectionProperty ) {
65
+ // // Don't override the property if it's part of the subresource system
66
+ if (isset ($ identifiers [$ propertyName ]) || isset ($ uriVariables [$ propertyName ])) {
68
67
continue ;
69
68
}
70
69
71
- $ identifierProperties = $ link ->getIdentifiers ();
72
- $ hasCompositeIdentifiers = 1 < \count ($ identifierProperties );
70
+ // Skip URI variables as sometime an uri variable is not the doctrine identifier
71
+ foreach ($ links as $ link ) {
72
+ if (\in_array ($ propertyName , $ link ->getIdentifiers (), true )) {
73
+ continue 2 ;
74
+ }
75
+ }
73
76
74
- foreach ($ identifierProperties as $ identifierProperty ) {
75
- $ reflectionProperty = $ reflectionProperties [$ identifierProperty ];
76
- $ reflectionProperty ->setValue ($ newData , $ this ->getIdentifierValue ($ identifiers , $ hasCompositeIdentifiers ? $ identifierProperty : null ));
77
+ if (($ newValue = $ reflectionProperty ->getValue ($ data )) !== $ reflectionProperty ->getValue ($ newData )) {
78
+ $ reflectionProperty ->setValue ($ newData , $ newValue );
77
79
}
78
80
}
79
81
} else {
80
- foreach ($ reflectionProperties as $ propertyName => $ reflectionProperty ) {
81
- // Don't override the property if it's part of the subresource system
82
- if (isset ($ uriVariables [$ propertyName ])) {
82
+ foreach (array_reverse ($ links ) as $ link ) {
83
+ if ($ link ->getExpandedValue () || !$ link ->getFromClass ()) {
83
84
continue ;
84
85
}
85
86
86
- foreach ($ links as $ link ) {
87
- $ identifierProperties = $ link ->getIdentifiers ();
88
- if (\in_array ($ propertyName , $ identifierProperties , true )) {
89
- continue ;
90
- }
87
+ $ identifierProperties = $ link ->getIdentifiers ();
88
+ $ hasCompositeIdentifiers = 1 < \count ($ identifierProperties );
91
89
92
- if (( $ newValue = $ reflectionProperty -> getValue ( $ data )) !== $ reflectionProperty -> getValue ( $ newData ) ) {
93
- $ reflectionProperty-> setValue ( $ newData , $ newValue ) ;
94
- }
90
+ foreach ( $ identifierProperties as $ identifierProperty ) {
91
+ $ reflectionProperty = $ reflectionProperties [ $ identifierProperty ] ;
92
+ $ reflectionProperty -> setValue ( $ newData , $ this -> getIdentifierValue ( $ identifiers , $ hasCompositeIdentifiers ? $ identifierProperty : null ));
95
93
}
96
94
}
97
95
}
@@ -115,7 +113,7 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
115
113
private function isDeferredExplicit (DoctrineObjectManager $ manager , $ data ): bool
116
114
{
117
115
$ classMetadata = $ manager ->getClassMetadata ($ this ->getObjectClass ($ data ));
118
- if (( $ classMetadata instanceof ClassMetadataInfo || $ classMetadata instanceof ClassMetadata) && method_exists ($ classMetadata , 'isChangeTrackingDeferredExplicit ' )) {
116
+ if ($ classMetadata && method_exists ($ classMetadata , 'isChangeTrackingDeferredExplicit ' )) { // @phpstan-ignore-line metadata can be null
119
117
return $ classMetadata ->isChangeTrackingDeferredExplicit ();
120
118
}
121
119
0 commit comments