@@ -35,6 +35,7 @@ public function __construct(
3535 private DiscriminatorStatementsGenerator $ discriminatorStatementsGeneratorSource ,
3636 private DiscriminatorStatementsGenerator $ discriminatorStatementsGeneratorTarget ,
3737 private CachedReflectionStatementsGenerator $ cachedReflectionStatementsGenerator ,
38+ private PropertyConditionsGenerator $ propertyConditionsGenerator ,
3839 ?Parser $ parser = null ,
3940 ) {
4041 $ this ->parser = $ parser ?? (new ParserFactory ())->createForHostVersion ();
@@ -161,12 +162,12 @@ private function constructorArguments(GeneratorMetadata $metadata): array
161162 * If source missing a constructor argument, check if there is a constructor argument in the context, otherwise we use the default value or throw exception.
162163 *
163164 * ```php
164- * {transformation of value}
165- * $constructarg = $value ?? (
166- * MapperContext::hasConstructorArgument($context, $target, 'propertyName')
167- * ? MapperContext::getConstructorArgument($context, $target, 'propertyName')
168- * : {defaultValueExpr} // default value or throw exception
169- * )
165+ *
166+ * if ( $value not defined) {
167+ * $constructarg = MapperContext::hasConstructorArgument($context, $target, 'propertyName') ? MapperContext::getConstructorArgument($context, $target, 'propertyName') : {defaultValueExpr} // default value or throw exception
168+ * } else {
169+ * $constructarg = transformation of value
170+ * }
170171 * ```
171172 *
172173 * @return array{Stmt[], Arg, string}|array{null, null, null}
@@ -177,6 +178,12 @@ private function constructorArgument(GeneratorMetadata $metadata, PropertyMetada
177178 $ constructVar = $ variableRegistry ->getVariableWithUniqueName ('constructArg ' );
178179 $ fieldValueExpr = $ propertyMetadata ->source ->accessor ?->getExpression($ variableRegistry ->getSourceInput ());
179180
181+ $ condition = $ this ->propertyConditionsGenerator ->generate (
182+ $ metadata ,
183+ $ propertyMetadata ,
184+ true
185+ );
186+
180187 if (null === $ fieldValueExpr ) {
181188 if (!($ propertyMetadata ->transformer instanceof AllowNullValueTransformerInterface)) {
182189 return [null , null , null ];
@@ -185,9 +192,6 @@ private function constructorArgument(GeneratorMetadata $metadata, PropertyMetada
185192 $ fieldValueExpr = new Expr \ConstFetch (new Name ('null ' ));
186193 }
187194
188- /* Get extract and transform statements for this property */
189- [$ output , $ propStatements ] = $ propertyMetadata ->transformer ->transform ($ fieldValueExpr , $ constructVar , $ propertyMetadata , $ variableRegistry ->getUniqueVariableScope (), $ variableRegistry ->getSourceInput ());
190-
191195 $ defaultValueExpr = new Expr \Throw_ (
192196 new Expr \New_ (new Name \FullyQualified (MissingConstructorArgumentsException::class), [
193197 new Arg (new Scalar \String_ (sprintf ('Cannot create an instance of "%s" from mapping data because its constructor requires the following parameters to be present : "$%s". ' , $ metadata ->mapperMetadata ->target , $ propertyMetadata ->target ->property ))),
@@ -206,36 +210,42 @@ private function constructorArgument(GeneratorMetadata $metadata, PropertyMetada
206210 $ defaultValueExpr = new Expr \ConstFetch (new Name ('null ' ));
207211 }
208212
209- if ($ defaultValueExpr instanceof Expr \Array_) {
210- // $constructarg = count($values) > 0 ? $values : {expression};
211- $ argumentAssignClosure = static fn (Expr $ expr ) => new Expr \Assign ($ constructVar , new Expr \Ternary (
212- new Expr \BinaryOp \Greater (new Expr \FuncCall (new Name ('count ' ), [new Arg ($ output )]), create_scalar_int (0 )),
213- $ output ,
214- $ expr ,
215- ));
216- } else {
217- // $constructarg = $values ?? {expression};
218- $ argumentAssignClosure = static fn (Expr $ expr ) => new Expr \Assign ($ constructVar , new Expr \BinaryOp \Coalesce ($ output , $ expr ));
213+ /* Get extract and transform statements for this property */
214+ [$ output , $ propStatements ] = $ propertyMetadata ->transformer ->transform ($ fieldValueExpr , $ constructVar , $ propertyMetadata , $ variableRegistry ->getUniqueVariableScope (), $ variableRegistry ->getSourceInput ());
215+
216+ if (!$ condition ) {
217+ return [
218+ [
219+ new Stmt \Expression (new Expr \Assign ($ constructVar , $ output )),
220+ ],
221+ new Arg ($ constructVar , name: new Identifier ($ parameter ->getName ())),
222+ $ parameter ->getName (),
223+ ];
219224 }
220225
221226 return [
222227 [
223- ...$ propStatements ,
224- new Stmt \Expression ($ argumentAssignClosure (
225- new Expr \Ternary (
226- new Expr \StaticCall (new Name \FullyQualified (MapperContext::class), 'hasConstructorArgument ' , [
227- new Arg ($ variableRegistry ->getContext ()),
228- new Arg (new Scalar \String_ ($ metadata ->mapperMetadata ->target )),
229- new Arg (new Scalar \String_ ($ propertyMetadata ->target ->property )),
230- ]),
231- new Expr \StaticCall (new Name \FullyQualified (MapperContext::class), 'getConstructorArgument ' , [
232- new Arg ($ variableRegistry ->getContext ()),
233- new Arg (new Scalar \String_ ($ metadata ->mapperMetadata ->target )),
234- new Arg (new Scalar \String_ ($ propertyMetadata ->target ->property )),
235- ]),
236- $ defaultValueExpr ,
237- ),
238- )),
228+ new Stmt \If_ ($ condition , [
229+ 'stmts ' => [
230+ ...$ propStatements ,
231+ new Stmt \Expression (new Expr \Assign ($ constructVar , $ output )),
232+ ],
233+ 'else ' => new Stmt \Else_ ([
234+ new Stmt \Expression (new Expr \Assign ($ constructVar , new Expr \Ternary (
235+ new Expr \StaticCall (new Name \FullyQualified (MapperContext::class), 'hasConstructorArgument ' , [
236+ new Arg ($ variableRegistry ->getContext ()),
237+ new Arg (new Scalar \String_ ($ metadata ->mapperMetadata ->target )),
238+ new Arg (new Scalar \String_ ($ propertyMetadata ->target ->property )),
239+ ]),
240+ new Expr \StaticCall (new Name \FullyQualified (MapperContext::class), 'getConstructorArgument ' , [
241+ new Arg ($ variableRegistry ->getContext ()),
242+ new Arg (new Scalar \String_ ($ metadata ->mapperMetadata ->target )),
243+ new Arg (new Scalar \String_ ($ propertyMetadata ->target ->property )),
244+ ]),
245+ $ defaultValueExpr ,
246+ ))),
247+ ]),
248+ ]),
239249 ],
240250 new Arg ($ constructVar , name: new Identifier ($ parameter ->getName ())),
241251 $ parameter ->getName (),
0 commit comments