Skip to content

Commit ccfc8fd

Browse files
committed
refactor: simplify call activity subprocess merge logic
1 parent 47202b9 commit ccfc8fd

File tree

1 file changed

+58
-22
lines changed

1 file changed

+58
-22
lines changed

ProcessMaker/Models/CallActivity.php

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)