Skip to content

Commit c9da124

Browse files
authored
Merge pull request #8841 from ProcessMaker/observation/FOUR-26342-b
Added a method to replace copied variables with new ones in the script
2 parents 74c8979 + 3a8551f commit c9da124

1 file changed

Lines changed: 183 additions & 4 deletions

File tree

ProcessMaker/ImportExport/Exporters/ScriptExporter.php

Lines changed: 183 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace ProcessMaker\ImportExport\Exporters;
44

5+
use Illuminate\Support\Facades\DB;
6+
use Illuminate\Support\Facades\Log;
57
use ProcessMaker\ImportExport\DependentType;
68
use ProcessMaker\Models\EnvironmentVariable;
79
use ProcessMaker\Models\ScriptCategory;
@@ -46,16 +48,19 @@ public function import() : bool
4648
$this->model->script_executor_id = $executor->id;
4749
}
4850

51+
// Update environment variable references in script code
52+
$this->updateEnvironmentVariableReferences();
53+
4954
// Pre-save cleanup for data source scripts to prevent constraint violations
5055
if ($this->mode === 'update' && $this->model->exists) {
5156
// Check if this script has any data source relationships that might cause conflicts
52-
$hasDataSourceRelationships = \DB::table('data_source_scripts')
57+
$hasDataSourceRelationships = DB::table('data_source_scripts')
5358
->where('script_id', $this->model->id)
5459
->exists();
5560

5661
if ($hasDataSourceRelationships) {
5762
// Clean up any conflicting records in data_source_scripts
58-
\DB::table('data_source_scripts')
63+
DB::table('data_source_scripts')
5964
->where('script_id', $this->model->id)
6065
->where('id', '!=', $this->model->id)
6166
->delete();
@@ -72,11 +77,185 @@ private function getEnvironmentVariables() : array
7277

7378
// Search for environment variable present in the code
7479
foreach ($environmentVariables as $variable) {
75-
if (preg_match('/[^a-zA-Z0-9\s]' . $variable->name . '[^a-zA-Z0-9\s]?/', $this->model->code)) {
76-
$environmentVariablesFound[] = $variable;
80+
// Multiple patterns to catch different usage styles
81+
$patterns = [
82+
// JavaScript patterns
83+
'/\bprocess\.env\.' . preg_quote($variable->name, '/') . '\b/', // process.env.VAR
84+
'/\bprocess\.env\[\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\]/', // process.env['VAR']
85+
86+
// PHP patterns
87+
'/\bconfig\s*\(\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\)/', // config('VAR')
88+
'/\benv\s*\(\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\)/', // env('VAR')
89+
'/\$_ENV\s*\[\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\]/', // $_ENV['VAR']
90+
'/\$_SERVER\s*\[\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\]/', // $_SERVER['VAR']
91+
92+
// Java patterns
93+
'/\bSystem\.getenv\s*\(\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\)/', // System.getenv("VAR")
94+
'/\bSystem\.getProperty\s*\(\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\)/', // System.getProperty("VAR")
95+
96+
// C# patterns
97+
'/\bEnvironment\.GetEnvironmentVariable\s*\(\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\)/', // Environment.GetEnvironmentVariable("VAR")
98+
'/\bConfigurationManager\.AppSettings\s*\[\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\]/', // ConfigurationManager.AppSettings["VAR"]
99+
100+
// Python patterns
101+
'/\bos\.environ\s*\[\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\]/', // os.environ['VAR']
102+
'/\bos\.environ\.get\s*\(\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\)/', // os.environ.get('VAR')
103+
'/\bos\.getenv\s*\(\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\)/', // os.getenv('VAR')
104+
105+
// Additional PHP patterns
106+
'/\bgetenv\s*\(\s*[\'"]' . preg_quote($variable->name, '/') . '[\'"]\s*\)/', // getenv('VAR')
107+
];
108+
109+
foreach ($patterns as $pattern) {
110+
if (preg_match($pattern, $this->model->code)) {
111+
$environmentVariablesFound[] = $variable;
112+
break;
113+
}
77114
}
78115
}
79116

80117
return $environmentVariablesFound;
81118
}
119+
120+
/**
121+
* Update environment variable references in script code when variables are renamed during import
122+
*
123+
* Note: This is a basic implementation. For a complete solution, you would need to:
124+
* 1. Track original variable names during export phase
125+
* 2. Map original names to new names after duplicate handling
126+
* 3. Update all references in the script code
127+
*/
128+
private function updateEnvironmentVariableReferences(): void
129+
{
130+
// Only process in copy mode where variables might be renamed
131+
if ($this->mode !== 'copy') {
132+
return;
133+
}
134+
135+
// Get the original variables that were detected during export
136+
$originalVariables = $this->getEnvironmentVariables();
137+
$variableMapping = [];
138+
139+
// Compare with the imported variables to detect name changes
140+
foreach ($this->getDependents(DependentType::ENVIRONMENT_VARIABLES, true) as $dependent) {
141+
$importedVar = $dependent->model;
142+
143+
// Find matching original variable by comparing the base name
144+
foreach ($originalVariables as $originalVar) {
145+
$mapped = false;
146+
147+
// Check if this is a renamed version (has suffix like _1, _2, etc.)
148+
if (preg_match('/^' . preg_quote($originalVar->name) . '_\d+$/', $importedVar->name)) {
149+
$variableMapping[$originalVar->name] = $importedVar->name;
150+
$mapped = true;
151+
}
152+
// Check if it's exactly the same name (no rename needed)
153+
elseif ($originalVar->name === $importedVar->name) {
154+
// Don't add to mapping since no replacement is needed
155+
$mapped = true;
156+
}
157+
// Check if it has other suffixes like _copy, _duplicate, etc.
158+
elseif (preg_match('/^' . preg_quote($originalVar->name) . '_(copy|duplicate|\d+)$/i', $importedVar->name)) {
159+
$variableMapping[$originalVar->name] = $importedVar->name;
160+
$mapped = true;
161+
}
162+
163+
if ($mapped) {
164+
break;
165+
}
166+
}
167+
}
168+
169+
// Update script code with new variable names
170+
if (!empty($variableMapping)) {
171+
$updatedCode = $this->model->code;
172+
173+
foreach ($variableMapping as $oldName => $newName) {
174+
// Update common patterns for environment variable access
175+
$patterns = [
176+
// JavaScript patterns - process.env.VARIABLE_NAME → process.env.VARIABLE_NAME_1
177+
'/\bprocess\.env\.' . preg_quote($oldName, '/') . '\b/',
178+
'/\bprocess\.env\[\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\]/',
179+
'/\bprocess\.env\[\s*"' . preg_quote($oldName, '/') . '"\s*\]/', // Double quotes
180+
181+
// PHP patterns
182+
// config('VARIABLE_NAME') → config('VARIABLE_NAME_1')
183+
'/\bconfig\s*\(\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\)/',
184+
// env('VARIABLE_NAME') → env('VARIABLE_NAME_1')
185+
'/\benv\s*\(\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\)/',
186+
// $_ENV['VARIABLE_NAME'] → $_ENV['VARIABLE_NAME_1']
187+
'/\$_ENV\s*\[\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\]/',
188+
// $_SERVER['VARIABLE_NAME'] → $_SERVER['VARIABLE_NAME_1']
189+
'/\$_SERVER\s*\[\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\]/',
190+
// getenv('VARIABLE_NAME') → getenv('VARIABLE_NAME_1')
191+
'/\bgetenv\s*\(\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\)/',
192+
// Config::get('VARIABLE_NAME') → Config::get('VARIABLE_NAME_1')
193+
'/\bConfig\s*::\s*get\s*\(\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\)/',
194+
195+
// Java patterns
196+
// System.getenv("VARIABLE_NAME") → System.getenv("VARIABLE_NAME_1")
197+
'/\bSystem\.getenv\s*\(\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\)/',
198+
// System.getProperty("VARIABLE_NAME") → System.getProperty("VARIABLE_NAME_1")
199+
'/\bSystem\.getProperty\s*\(\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\)/',
200+
201+
// C# patterns
202+
// Environment.GetEnvironmentVariable("VARIABLE_NAME") → Environment.GetEnvironmentVariable("VARIABLE_NAME_1")
203+
'/\bEnvironment\.GetEnvironmentVariable\s*\(\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\)/',
204+
// ConfigurationManager.AppSettings["VARIABLE_NAME"] → ConfigurationManager.AppSettings["VARIABLE_NAME_1"]
205+
'/\bConfigurationManager\.AppSettings\s*\[\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\]/',
206+
207+
// Python patterns
208+
// os.environ['VARIABLE_NAME'] → os.environ['VARIABLE_NAME_1']
209+
'/\bos\.environ\s*\[\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\]/',
210+
// os.environ.get('VARIABLE_NAME') → os.environ.get('VARIABLE_NAME_1')
211+
'/\bos\.environ\.get\s*\(\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\)/',
212+
// os.getenv('VARIABLE_NAME') → os.getenv('VARIABLE_NAME_1')
213+
'/\bos\.getenv\s*\(\s*[\'"]' . preg_quote($oldName, '/') . '[\'"]\s*\)/',
214+
];
215+
216+
foreach ($patterns as $patternIndex => $pattern) {
217+
$updatedCode = preg_replace_callback($pattern, function ($matches) use ($oldName, $newName, $patternIndex) {
218+
$original = $matches[0];
219+
220+
// Handle different replacement patterns
221+
switch ($patternIndex) {
222+
case 0: // process.env.VARIABLE_NAME
223+
return str_replace('process.env.' . $oldName, 'process.env.' . $newName, $original);
224+
case 1: // process.env['VARIABLE_NAME']
225+
case 2: // process.env["VARIABLE_NAME"]
226+
return str_replace($oldName, $newName, $original);
227+
case 6: // System.getenv for Java
228+
return str_replace($oldName, $newName, $original);
229+
case 7: // System.getProperty for Java
230+
return str_replace($oldName, $newName, $original);
231+
case 8: // Environment.GetEnvironmentVariable for C#
232+
return str_replace($oldName, $newName, $original);
233+
case 9: // ConfigurationManager.AppSettings for C#
234+
return str_replace($oldName, $newName, $original);
235+
case 10: // os.environ for Python
236+
case 11: // os.environ.get for Python
237+
case 12: // os.getenv for Python
238+
return str_replace($oldName, $newName, $original);
239+
default: // All other patterns (PHP)
240+
return str_replace($oldName, $newName, $original);
241+
}
242+
}, $updatedCode);
243+
}
244+
}
245+
246+
// Only update if changes were made
247+
if ($updatedCode !== $this->model->code) {
248+
$this->model->code = $updatedCode;
249+
250+
// Log the variable name changes (summary)
251+
Log::info('ScriptExporter: Updated variable references in script', [
252+
'script_id' => $this->model->id,
253+
'script_title' => $this->model->title,
254+
'variables_updated' => count($variableMapping),
255+
'mappings' => $variableMapping,
256+
'mode' => $this->mode,
257+
]);
258+
}
259+
}
260+
}
82261
}

0 commit comments

Comments
 (0)