@@ -46,12 +46,12 @@ public function map(DataType|string $type, array|string $data): ?object
4646 return $ class ::from ($ data );
4747 }
4848
49- $ functionName = self ::MAPPER_FUNCTION_PREFIX . \md5 ($ class );
49+ $ functionName = self ::MAPPER_FUNCTION_PREFIX . \md5 ($ class . ( $ type instanceof DataType && $ type -> isNullable ? ' 1 ' : ' 0 ' ) );
5050 if ($ this ->mapper ->config ->classCacheKeySource === 'md5 ' || $ this ->mapper ->config ->classCacheKeySource === 'modified ' ) {
5151 $ reflection = new ReflectionClass ($ class );
5252 $ functionName = match ($ this ->mapper ->config ->classCacheKeySource ) {
53- 'md5 ' => self ::MAPPER_FUNCTION_PREFIX . \md5_file ($ reflection ->getFileName ()),
54- 'modified ' => self ::MAPPER_FUNCTION_PREFIX . \md5 (\filemtime ($ reflection ->getFileName ())),
53+ 'md5 ' => self ::MAPPER_FUNCTION_PREFIX . \md5 ( \ md5_file ($ reflection ->getFileName ()) . $ functionName ),
54+ 'modified ' => self ::MAPPER_FUNCTION_PREFIX . \md5 (\filemtime ($ reflection ->getFileName ()) . $ functionName ),
5555 };
5656 }
5757
@@ -62,6 +62,7 @@ public function map(DataType|string $type, array|string $data): ?object
6262 $ this ->createObjectMappingFunction (
6363 $ this ->classBluePrinter ->print ($ class ),
6464 $ functionName ,
65+ $ type instanceof DataType && $ type ->isNullable ,
6566 ),
6667 );
6768 }
@@ -88,14 +89,24 @@ public function mapperDirectory(): string
8889 return \rtrim ($ dir , \DIRECTORY_SEPARATOR );
8990 }
9091
91- private function createObjectMappingFunction (ClassBluePrint $ blueprint , string $ mapFunctionName ): string
92+ private function createObjectMappingFunction (ClassBluePrint $ blueprint , string $ mapFunctionName, bool $ isNullable ): string
9293 {
9394 $ tab = ' ' ;
95+ $ content = '' ;
96+
97+ if ($ isNullable ) {
98+ $ content .= $ tab . $ tab . 'if ($data === [] && $mapper->config->nullObjectFromEmptyArray) { ' . \PHP_EOL ;
99+ $ content .= $ tab . $ tab . $ tab . 'return null; ' . \PHP_EOL ;
100+ $ content .= $ tab . $ tab . '} ' . \PHP_EOL . \PHP_EOL ;
101+ }
94102
95103 // Instantiate a new object
96104 $ args = [];
97105 foreach ($ blueprint ->constructorArguments as $ name => $ argument ) {
98106 $ arg = "\$data[' {$ name }'] " ;
107+ if ($ argument ['type ' ]->isNullable ()) {
108+ $ arg = "( {$ arg } ?? null) " ;
109+ }
99110
100111 if ($ argument ['type ' ] !== null ) {
101112 $ arg = $ this ->castInMapperFunction ($ arg , $ argument ['type ' ], $ blueprint );
@@ -107,7 +118,7 @@ private function createObjectMappingFunction(ClassBluePrint $blueprint, string $
107118
108119 $ args [] = $ arg ;
109120 }
110- $ content = '$x = new ' . $ blueprint ->namespacedClassName . '( ' . \implode (', ' , $ args ) . '); ' ;
121+ $ content .= $ tab . $ tab . '$x = new ' . $ blueprint ->namespacedClassName . '( ' . \implode (', ' , $ args ) . '); ' ;
111122
112123 // Map properties
113124 foreach ($ blueprint ->properties as $ name => $ property ) {
@@ -118,7 +129,12 @@ private function createObjectMappingFunction(ClassBluePrint $blueprint, string $
118129 continue ;
119130 }
120131
121- $ propertyMap = $ this ->castInMapperFunction ("\$data[' {$ name }'] " , $ property ['type ' ], $ blueprint );
132+ $ propertyName = "\$data[' {$ name }'] " ;
133+ if ($ property ['type ' ]->isNullable ()) {
134+ $ propertyName = "( {$ propertyName } ?? null) " ;
135+ }
136+
137+ $ propertyMap = $ this ->castInMapperFunction ($ propertyName , $ property ['type ' ], $ blueprint );
122138 if (\array_key_exists ('default ' , $ property )) {
123139 $ propertyMap = $ this ->wrapDefault ($ propertyMap , $ name , $ property ['default ' ]);
124140 }
@@ -151,7 +167,7 @@ private function createObjectMappingFunction(ClassBluePrint $blueprint, string $
151167 if (! \\function_exists(' {$ mapFunctionName }')) {
152168 function {$ mapFunctionName }( {$ mapperClass } \$mapper, array \$data)
153169 {
154- {$ content }
170+ {$ content }
155171
156172 return \$x;
157173 }
0 commit comments