66
77use PHPModelGenerator \Exception \ComposedValue \InvalidComposedValueException ;
88use PHPModelGenerator \Model \GeneratorConfiguration ;
9+ use PHPModelGenerator \Model \MethodInterface ;
910use PHPModelGenerator \Model \Property \CompositionPropertyDecorator ;
1011use PHPModelGenerator \Model \Property \PropertyInterface ;
1112use PHPModelGenerator \Model \Validator ;
1718 */
1819class ComposedPropertyValidator extends AbstractComposedPropertyValidator
1920{
21+ private $ modifiedValuesMethod ;
22+
2023 public function __construct (
2124 GeneratorConfiguration $ generatorConfiguration ,
2225 PropertyInterface $ property ,
2326 array $ composedProperties ,
2427 string $ compositionProcessor ,
2528 array $ validatorVariables
2629 ) {
30+ $ this ->modifiedValuesMethod = '_getModifiedValues_ ' . substr (md5 (spl_object_hash ($ this )), 0 , 5 );
2731 $ this ->isResolved = true ;
2832
2933 parent ::__construct (
3034 $ generatorConfiguration ,
3135 $ property ,
3236 DIRECTORY_SEPARATOR . 'Validator ' . DIRECTORY_SEPARATOR . 'ComposedItem.phptpl ' ,
33- $ validatorVariables ,
37+ array_merge ( $ validatorVariables, [ ' modifiedValuesMethod ' => $ this -> modifiedValuesMethod ]) ,
3438 $ this ->getExceptionByProcessor ($ compositionProcessor ),
3539 ['&$succeededCompositionElements ' , '&$compositionErrorCollection ' ]
3640 );
@@ -39,6 +43,74 @@ public function __construct(
3943 $ this ->composedProperties = $ composedProperties ;
4044 }
4145
46+ /**
47+ * TODO: add method only if nested objects contain filter (else also skip method call)
48+ */
49+ public function getCheck (): string
50+ {
51+ /**
52+ * Add a method to the schema to gather values from a nested object which are modified.
53+ * This is required to adopt filter changes to the values which are passed into a merged property
54+ */
55+ $ this ->scope ->addMethod (
56+ $ this ->modifiedValuesMethod ,
57+ new class ($ this ->composedProperties , $ this ->modifiedValuesMethod ) implements MethodInterface {
58+ /** @var CompositionPropertyDecorator[] $compositionProperties */
59+ private $ compositionProperties ;
60+ /** @var string */
61+ private $ modifiedValuesMethod ;
62+
63+ public function __construct (array $ compositionProperties , string $ modifiedValuesMethod )
64+ {
65+ $ this ->compositionProperties = $ compositionProperties ;
66+ $ this ->modifiedValuesMethod = $ modifiedValuesMethod ;
67+ }
68+
69+ public function getCode (): string
70+ {
71+ $ defaultValueMap = [];
72+ $ propertyAccessors = [];
73+ foreach ($ this ->compositionProperties as $ compositionProperty ) {
74+ if (!$ compositionProperty ->getNestedSchema ()) {
75+ continue ;
76+ }
77+
78+ foreach ($ compositionProperty ->getNestedSchema ()->getProperties () as $ property ) {
79+ $ propertyAccessors [$ property ->getName ()] = 'get ' . ucfirst ($ property ->getAttribute ());
80+
81+ if ($ property ->getDefaultValue () !== null ) {
82+ $ defaultValueMap [] = $ property ->getName ();
83+ }
84+ }
85+ }
86+
87+ return sprintf ('
88+ private function %s(array $originalModelData, object $nestedCompositionObject): array {
89+ $modifiedValues = [];
90+ $defaultValueMap = %s;
91+
92+ foreach (%s as $key => $accessor) {
93+ if ((isset($originalModelData[$key]) || in_array($key, $defaultValueMap))
94+ && method_exists($nestedCompositionObject, $accessor)
95+ && ($modifiedValue = $nestedCompositionObject->$accessor()) !== ($originalModelData[$key] ?? !$modifiedValue)
96+ ) {
97+ $modifiedValues[$key] = $modifiedValue;
98+ }
99+ }
100+
101+ return $modifiedValues;
102+ } ' ,
103+ $ this ->modifiedValuesMethod ,
104+ var_export ($ defaultValueMap , true ),
105+ var_export ($ propertyAccessors , true )
106+ );
107+ }
108+ }
109+ );
110+
111+ return parent ::getCheck ();
112+ }
113+
42114 /**
43115 * Initialize all variables which are required to execute a composed property validator
44116 *
0 commit comments