@@ -97,22 +97,10 @@ 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.
101- $ updatedKeys = method_exists ($ store , 'getUpdated ' )
102- ? $ store ->getUpdated ()
103- : null ;
104-
105- 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 ));
115- }
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 );
116104
117105 $ dataManager = new DataManager ();
118106 $ dataManager ->updateData ($ token , $ data );
@@ -125,6 +113,62 @@ protected function completeSubprocess(TokenInterface $token, ExecutionInstanceIn
125113 return $ this ;
126114 }
127115
116+ /**
117+ * Decide which data from the subprocess should be merged based on updated keys.
118+ */
119+ protected function resolveUpdatedData ($ store , array $ allData ): array
120+ {
121+ $ updatedKeys = method_exists ($ store , 'getUpdated ' )
122+ ? $ store ->getUpdated ()
123+ : null ;
124+
125+ if ($ updatedKeys === null ) {
126+ return $ allData ;
127+ }
128+
129+ if ($ updatedKeys === []) {
130+ return [];
131+ }
132+
133+ $ updatedKeys = array_values ((array ) $ updatedKeys );
134+
135+ return array_intersect_key ($ allData , array_flip ($ updatedKeys ));
136+ }
137+
138+ /**
139+ * Merge keys that exist only in the subprocess data.
140+ */
141+ protected 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 ;
146+ }
147+
148+ return $ data + array_intersect_key ($ allData , array_flip ($ newKeys ));
149+ }
150+
151+ /**
152+ * Merge keys that changed in the subprocess but may not have been tracked.
153+ */
154+ protected 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+ }
162+
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 ));
170+ }
171+
128172 /**
129173 * Catch a subprocess error
130174 *
0 commit comments