@@ -956,19 +956,60 @@ public function testNormalizeWithMethodNamesSimilarToAccessors()
956
956
], $ normalized );
957
957
}
958
958
959
- public function testNormalizeObjectWithBooleanPropertyAndIsserMethodWithSameName ()
959
+ public function testNormalizeObjectWithPublicPropertyAccessorPrecedence ()
960
960
{
961
961
$ classMetadataFactory = new ClassMetadataFactory (new AttributeLoader ());
962
962
$ normalizer = new ObjectNormalizer ($ classMetadataFactory );
963
963
964
- $ object = new ObjectWithBooleanPropertyAndIsserWithSameName ();
964
+ $ object = new ObjectWithPropertyAndAllAccessorMethods (
965
+ 'foo ' ,
966
+ );
965
967
$ normalized = $ normalizer ->normalize ($ object );
966
968
969
+ // The getter method should take precedence over all other accessor methods
967
970
$ this ->assertSame ([
968
971
'foo ' => 'foo ' ,
969
- 'isFoo ' => true ,
970
972
], $ normalized );
971
973
}
974
+
975
+ public function testNormalizeObjectWithPropertyAndAccessorMethodsWithSameName ()
976
+ {
977
+ $ classMetadataFactory = new ClassMetadataFactory (new AttributeLoader ());
978
+ $ normalizer = new ObjectNormalizer ($ classMetadataFactory );
979
+
980
+ $ object = new ObjectWithPropertyAndAccessorSameName (
981
+ 'foo ' ,
982
+ 'getFoo ' ,
983
+ 'canFoo ' ,
984
+ 'hasFoo ' ,
985
+ 'isFoo '
986
+ );
987
+ $ normalized = $ normalizer ->normalize ($ object );
988
+
989
+ // Previously, only the 'foo' property was extracted, all other properties starting with accessor verbs were
990
+ // converted to 'foo'. Now accessor methods with exactly the same name as the property take precedence.
991
+ $ this ->assertSame ([
992
+ 'getFoo ' => 'getFoo ' ,
993
+ 'canFoo ' => 'canFoo ' ,
994
+ 'hasFoo ' => 'hasFoo ' ,
995
+ 'isFoo ' => 'isFoo ' ,
996
+ // The getter method should be used for both properties, thus we get 'getFoo' instead of 'foo'
997
+ 'foo ' => 'getFoo ' ,
998
+ ], $ normalized );
999
+
1000
+ $ denormalized = $ this ->normalizer ->denormalize ($ normalized , ObjectWithPropertyAndAccessorSameName::class);
1001
+
1002
+ $ this ->assertSame ('getFoo ' , $ denormalized ->getFoo ());
1003
+
1004
+ // On the initial object the value was 'foo', but the normalizer prefers the accessor method 'getFoo'
1005
+ // Thus on the denoramilzed object the value is 'getFoo'
1006
+ $ this ->assertSame ('foo ' , $ object ->foo );
1007
+ $ this ->assertSame ('getFoo ' , $ denormalized ->foo );
1008
+
1009
+ $ this ->assertSame ('hasFoo ' , $ denormalized ->hasFoo ());
1010
+ $ this ->assertSame ('canFoo ' , $ denormalized ->canFoo ());
1011
+ $ this ->assertSame ('isFoo ' , $ denormalized ->isFoo ());
1012
+ }
972
1013
}
973
1014
974
1015
class ProxyObjectDummy extends ObjectDummy
@@ -1312,16 +1353,58 @@ public function isolate()
1312
1353
}
1313
1354
}
1314
1355
1315
- class ObjectWithBooleanPropertyAndIsserWithSameName
1316
- {
1317
- private $ foo = 'foo ' ;
1318
- private $ isFoo = true ;
1356
+ class ObjectWithPropertyAndAllAccessorMethods {
1357
+ public function __construct (
1358
+ private $ foo ,
1359
+ ) {
1360
+ }
1361
+
1362
+ public function canFoo ()
1363
+ {
1364
+ return 'canFoo ' ;
1365
+ }
1319
1366
1320
1367
public function getFoo ()
1321
1368
{
1322
1369
return $ this ->foo ;
1323
1370
}
1324
1371
1372
+ public function hasFoo ()
1373
+ {
1374
+ return 'hasFoo ' ;
1375
+ }
1376
+
1377
+ public function isFoo ()
1378
+ {
1379
+ return 'isFoo ' ;
1380
+ }
1381
+ }
1382
+
1383
+ class ObjectWithPropertyAndAccessorSameName {
1384
+ public function __construct (
1385
+ public $ foo ,
1386
+ private $ getFoo ,
1387
+ private $ canFoo = null ,
1388
+ private $ hasFoo = null ,
1389
+ private $ isFoo = null ,
1390
+ ) {
1391
+ }
1392
+
1393
+ public function getFoo ()
1394
+ {
1395
+ return $ this ->getFoo ;
1396
+ }
1397
+
1398
+ public function canFoo ()
1399
+ {
1400
+ return $ this ->canFoo ;
1401
+ }
1402
+
1403
+ public function hasFoo ()
1404
+ {
1405
+ return $ this ->hasFoo ;
1406
+ }
1407
+
1325
1408
public function isFoo ()
1326
1409
{
1327
1410
return $ this ->isFoo ;
0 commit comments