22
33namespace ProcessMaker \ImportExport \Exporters ;
44
5+ use Illuminate \Support \Facades \DB ;
6+ use Illuminate \Support \Facades \Log ;
57use ProcessMaker \ImportExport \DependentType ;
68use ProcessMaker \Models \EnvironmentVariable ;
79use 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