import re file_path = 'includes/actions.php' try: with open(file_path, 'r') as f: content = f.read() except FileNotFoundError: print(f"Error: {file_path} not found.") exit(1) # New function implementation new_function = r""" function parse_import_file($file_input) { if (!isset($file_input['error']) || $file_input['error'] !== UPLOAD_ERR_OK) { $_SESSION['import_error'] = 'Upload error code: ' . ($file_input['error'] ?? 'unknown'); return false; } $ext = strtolower(pathinfo($file_input['name'], PATHINFO_EXTENSION)); $rows = []; if ($ext === 'csv') { $handle = fopen($file_input['tmp_name'], 'r'); if ($handle === false) { $_SESSION['import_error'] = 'Failed to open CSV file.'; return false; } # Skip header fgetcsv($handle); while (($row = fgetcsv($handle)) !== false) { if (array_filter($row)) { $rows[] = $row; } } fclose($handle); if (empty($rows)) { $_SESSION['import_error'] = 'CSV file is empty or could not be parsed.'; } } elseif ($ext === 'xlsx' || $ext === 'xls') { require_once __DIR__ . '/SimpleXLSX.php'; if ($xlsx = \Shuchkin\SimpleXLSX::parse($file_input['tmp_name'])) { $rows = $xlsx->rows(); array_shift($rows); # Skip header if (empty($rows)) { $_SESSION['import_error'] = 'Excel file is empty.'; } } else { $_SESSION['import_error'] = 'SimpleXLSX Error: ' . \Shuchkin\SimpleXLSX::parseError(); return false; } } else { $_SESSION['import_error'] = "Unsupported file extension: $ext. Please upload .csv or .xlsx"; return false; } return $rows; }""" # Escape specific regex characters in the new function if we used it in regex, but here we use it as replacement string. # We need to escape backslashes in the replacement string if we use re.sub, because \1, \g<1> etc have meaning. # However, our replacement string doesn't have those. But PHP has backslashes (namespaces). # So we need to escape backslashes for python string, and then for re.sub. # Actually, let's use string.replace() if possible, but we don't know the exact content of the old function to replace it exactly if it varies. # But we know the structure. # Let's try to identify the start and end of the function. start_marker = "function parse_import_file($file_input) {" end_marker = "return $rows;\n }" start_pos = content.find(start_marker) if start_pos != -1: end_pos = content.find(end_marker, start_pos) if end_pos != -1: end_pos += len(end_marker) # Replace the function content = content[:start_pos] + new_function.strip() + "\n" + content[end_pos:] print("Replaced function parse_import_file.") else: print("Could not find end of function parse_import_file.") # Fallback to regex if simple find fails (e.g. whitespace diff) pattern = r"function parse_import_file\(\$file_input\) \{[\s\S]+?return \$rows;\s+\}" if re.search(pattern, content): content = re.sub(pattern, new_function, content, count=1) print("Replaced function parse_import_file using regex.") else: print("Could not find function parse_import_file using regex.") else: print("Could not find start of function parse_import_file.") # Fallback to regex pattern = r"function parse_import_file\(\$file_input\) \{[\s\S]+?return \$rows;\s+\}" if re.search(pattern, content): content = re.sub(pattern, new_function, content, count=1) print("Replaced function parse_import_file using regex (fallback).") else: print("Could not find function parse_import_file using regex (fallback).") # Update the calling logic old_msg = "$_SESSION['flash_message'] = 'Failed to parse file or empty.';" new_msg = "$_SESSION['flash_message'] = $_SESSION['import_error'] ?? 'Failed to parse file or empty.'; unset($_SESSION['import_error']);" if old_msg in content: content = content.replace(old_msg, new_msg) print("Updated error message logic.") else: print("Could not find old error message logic.") with open(file_path, 'w') as f: f.write(content) print("Finished updating includes/actions.php")