@@ -97,40 +97,76 @@ protected function completeSubprocess(TokenInterface $token, ExecutionInstanceIn
9797 $ store = $ closedInstance ->getDataStore ();
9898 $ allData = $ store ->getData ();
9999
100- // Determine which data should be merged back from the subprocess.
100+ $ data = $ this ->resolveUpdatedData ($ store , $ allData );
101+ $ parentData = $ token ->getInstance ()->getDataStore ()->getData ();
102+ $ data = $ this ->mergeNewKeys ($ data , $ allData , $ parentData );
103+ $ data = $ this ->mergeChangedKeys ($ data , $ allData , $ parentData );
104+
105+ $ dataManager = new DataManager ();
106+ $ dataManager ->updateData ($ token , $ data );
107+ $ token ->getInstance ()->getProcess ()->getEngine ()->runToNextState ();
108+
109+ // Complete the sub process call
110+ $ this ->completeSubprocessBase ($ token );
111+ $ this ->synchronizeInstances ($ instance , $ token ->getInstance ());
112+
113+ return $ this ;
114+ }
115+
116+ /**
117+ * Decide which data from the subprocess should be merged based on updated keys.
118+ */
119+ private function resolveUpdatedData ($ store , array $ allData ): array
120+ {
101121 $ updatedKeys = method_exists ($ store , 'getUpdated ' )
102122 ? $ store ->getUpdated ()
103123 : null ;
104124
105125 if ($ updatedKeys === null ) {
106- // Legacy behavior or no tracking available: copy all data.
107- $ data = $ allData ;
108- } elseif ($ updatedKeys === []) {
109- // Nothing was updated in the subprocess: do not merge anything.
110- $ data = [];
111- } else {
112- // Merge only the explicitly updated keys.
113- $ updatedKeys = array_values ((array ) $ updatedKeys );
114- $ data = array_intersect_key ($ allData , array_flip ($ updatedKeys ));
126+ return $ allData ;
115127 }
116128
117- $ parentData = $ token ->getInstance ()->getDataStore ()->getData ();
129+ if ($ updatedKeys === []) {
130+ return [];
131+ }
132+
133+ $ updatedKeys = array_values ((array ) $ updatedKeys );
134+
135+ return array_intersect_key ($ allData , array_flip ($ updatedKeys ));
136+ }
118137
119- // Ensure new keys created in the subprocess are merged even if getUpdated() missed them.
120- $ newKeys = array_diff (array_keys ($ allData ?? []), array_keys ($ parentData ?? []));
121- if (!empty ($ newKeys )) {
122- $ data = $ data + array_intersect_key ($ allData , array_flip ($ newKeys ));
138+ /**
139+ * Merge keys that exist only in the subprocess data.
140+ */
141+ private function mergeNewKeys (array $ data , array $ allData , array $ parentData ): array
142+ {
143+ $ newKeys = array_diff (array_keys ($ allData ), array_keys ($ parentData ));
144+ if (empty ($ newKeys )) {
145+ return $ data ;
123146 }
124147
125- $ dataManager = new DataManager ();
126- $ dataManager ->updateData ($ token , $ data );
127- $ token ->getInstance ()->getProcess ()->getEngine ()->runToNextState ();
148+ return $ data + array_intersect_key ($ allData , array_flip ($ newKeys ));
149+ }
128150
129- // Complete the sub process call
130- $ this ->completeSubprocessBase ($ token );
131- $ this ->synchronizeInstances ($ instance , $ token ->getInstance ());
151+ /**
152+ * Merge keys that changed in the subprocess but may not have been tracked.
153+ */
154+ private function mergeChangedKeys (array $ data , array $ allData , array $ parentData ): array
155+ {
156+ $ changedKeys = [];
157+ foreach ($ allData as $ key => $ value ) {
158+ if (array_key_exists ($ key , $ parentData ) && $ parentData [$ key ] !== $ value ) {
159+ $ changedKeys [] = $ key ;
160+ }
161+ }
132162
133- return $ this ;
163+ if (empty ($ changedKeys )) {
164+ return $ data ;
165+ }
166+
167+ $ pendingKeys = array_diff ($ changedKeys , array_keys ($ data ));
168+
169+ return $ data + array_intersect_key ($ allData , array_flip ($ pendingKeys ));
134170 }
135171
136172 /**
0 commit comments