217 lines
7.4 KiB
PHP
217 lines
7.4 KiB
PHP
<?php
|
|
// api.php
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
function load_env($path) {
|
|
if (!file_exists($path)) {
|
|
error_log(".env file not found at " . $path);
|
|
return;
|
|
}
|
|
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
foreach ($lines as $line) {
|
|
if (strpos(trim($line), '#') === 0) {
|
|
continue;
|
|
}
|
|
list($name, $value) = explode('=', $line, 2);
|
|
$name = trim($name);
|
|
$value = trim($value);
|
|
if (!array_key_exists($name, $_SERVER) && !array_key_exists($name, $_ENV)) {
|
|
putenv(sprintf('%s=%s', $name, $value));
|
|
$_ENV[$name] = $value;
|
|
$_SERVER[$name] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
function get_csv_sample($filePath) {
|
|
$sample = [];
|
|
$handle = fopen($filePath, 'r');
|
|
if ($handle === false) {
|
|
return null;
|
|
}
|
|
$headers = fgetcsv($handle);
|
|
$sample[] = implode(',', $headers);
|
|
|
|
$i = 0;
|
|
while (($row = fgetcsv($handle)) !== false && $i < 5) {
|
|
$sample[] = implode(',', $row);
|
|
$i++;
|
|
}
|
|
fclose($handle);
|
|
return implode('\n', $sample);
|
|
}
|
|
|
|
function call_openai_api($inputSample, $outputSample, $customInstructions) {
|
|
$apiKey = getenv('OPENAI_API_KEY');
|
|
if (!$apiKey) {
|
|
return ['error' => 'OpenAI API key not configured.'];
|
|
}
|
|
|
|
$prompt = "I have two CSV files. I want to convert the input file to the output file format.\n\n";
|
|
$prompt .= "Here is a sample of the input CSV file:\n---\n" . $inputSample . "\n---\n\n";
|
|
$prompt .= "Here is a sample of the output CSV file:\n---" . $outputSample . "---\n\n";
|
|
if (!empty($customInstructions)) {
|
|
$prompt .= "Additionally, here are some custom instructions to follow:\n---" . $customInstructions . "---\n\n";
|
|
}
|
|
$prompt .= "Please generate a PHP script that contains a single function `convert_csv($input_file_path, $output_file_path)`.\n";
|
|
$prompt .= "This function should read the data from the `$input_file_path`, transform it into the format of the output sample, and write the result to `$output_file_path`.\n";
|
|
$prompt .= "The script should handle CSV headers correctly. Do not include any explanations, just the raw PHP code starting with `<?php`.";
|
|
|
|
$data = [
|
|
'model' => 'gpt-5',
|
|
'messages' => [
|
|
[
|
|
'role' => 'user',
|
|
'content' => $prompt
|
|
]
|
|
]
|
|
];
|
|
|
|
$ch = curl_init('https://api.openai.com/v1/chat/completions');
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
'Content-Type: application/json',
|
|
'Authorization: Bearer ' . $apiKey
|
|
]);
|
|
|
|
$response = curl_exec($ch);
|
|
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
if ($httpcode != 200) {
|
|
return ['error' => 'Failed to connect to OpenAI API. Response: ' . $response];
|
|
}
|
|
|
|
$result = json_decode($response, true);
|
|
|
|
if (isset($result['choices'][0]['message']['content'])) {
|
|
$php_code = $result['choices'][0]['message']['content'];
|
|
// Clean up the response to get only the code
|
|
if (strpos($php_code, '```php') !== false) {
|
|
$php_code = substr($php_code, strpos($php_code, '```php') + 5);
|
|
$php_code = substr($php_code, 0, strrpos($php_code, '```'));
|
|
}
|
|
if (strpos($php_code, '<?php') === false) {
|
|
$php_code = "<?php\n" . $php_code;
|
|
}
|
|
return ['success' => true, 'code' => $php_code];
|
|
}
|
|
|
|
return ['error' => 'Could not extract PHP code from OpenAI response.', 'details' => $result];
|
|
}
|
|
|
|
load_env(__DIR__ . '/.env');
|
|
$action = $_POST['action'] ?? $_GET['action'] ?? '';
|
|
|
|
function sanitize_filename($filename) {
|
|
// Remove PHP extension if present
|
|
if (substr($filename, -4) === '.php') {
|
|
$filename = substr($filename, 0, -4);
|
|
}
|
|
// Replace spaces and special characters with hyphens
|
|
$filename = preg_replace('/[^a-zA-Z0-9_\.-]/', '-', $filename);
|
|
// Remove leading/trailing hyphens
|
|
$filename = trim($filename, '-');
|
|
// Ensure it's not empty
|
|
if (empty($filename)) {
|
|
return 'mapping-' . time();
|
|
}
|
|
return $filename . '.php';
|
|
}
|
|
|
|
if ($action === 'list_mappings') {
|
|
$mappingDir = __DIR__ . '/mappings';
|
|
$files = glob($mappingDir . '/*.php');
|
|
$mappings = array_map(function($file) {
|
|
return basename($file);
|
|
}, $files);
|
|
echo json_encode(['success' => true, 'mappings' => $mappings]);
|
|
exit;
|
|
}
|
|
|
|
if ($action === 'build_mapping') {
|
|
if (!isset($_FILES['inputSample']) || !isset($_FILES['outputSample'])) {
|
|
echo json_encode(['success' => false, 'error' => 'Input and output sample files are required.']);
|
|
exit;
|
|
}
|
|
|
|
$inputTmpPath = $_FILES['inputSample']['tmp_name'];
|
|
$outputTmpPath = $_FILES['outputSample']['tmp_name'];
|
|
|
|
$inputSampleContent = get_csv_sample($inputTmpPath);
|
|
$outputSampleContent = get_csv_sample($outputTmpPath);
|
|
$customInstructions = $_POST['customInstructions'] ?? '';
|
|
|
|
if ($inputSampleContent === null || $outputSampleContent === null) {
|
|
echo json_encode(['success' => false, 'error' => 'Failed to read sample files.']);
|
|
exit;
|
|
}
|
|
|
|
$result = call_openai_api($inputSampleContent, $outputSampleContent, $customInstructions);
|
|
|
|
if (isset($result['error'])) {
|
|
echo json_encode(['success' => false, 'error' => $result['error'], 'details' => $result['details'] ?? null]);
|
|
exit;
|
|
}
|
|
|
|
$mappingDir = __DIR__ . '/mappings';
|
|
if (!is_dir($mappingDir)) {
|
|
mkdir($mappingDir, 0775, true);
|
|
}
|
|
|
|
$mappingName = $_POST['mappingName'] ?? '';
|
|
if (empty($mappingName)) {
|
|
$inputName = pathinfo($_FILES['inputSample']['name'], PATHINFO_FILENAME);
|
|
$outputName = pathinfo($_FILES['outputSample']['name'], PATHINFO_FILENAME);
|
|
$mappingName = $inputName . '-to-' . $outputName;
|
|
}
|
|
|
|
$mappingFile = sanitize_filename($mappingName);
|
|
$mappingPath = $mappingDir . '/' . $mappingFile;
|
|
|
|
file_put_contents($mappingPath, $result['code']);
|
|
|
|
echo json_encode(['success' => true, 'mapping_file' => 'mappings/' . $mappingFile]);
|
|
exit;
|
|
}
|
|
|
|
if ($action === 'convert') {
|
|
if (!isset($_FILES['fullInputFile']) || !isset($_POST['mappingFile'])) {
|
|
echo json_encode(['success' => false, 'error' => 'Input file and mapping file are required.']);
|
|
exit;
|
|
}
|
|
|
|
$mappingFile = $_POST['mappingFile'];
|
|
if (!file_exists($mappingFile)) {
|
|
echo json_encode(['success' => false, 'error' => 'Mapping file not found.']);
|
|
exit;
|
|
}
|
|
|
|
require_once $mappingFile;
|
|
|
|
if (!function_exists('convert_csv')) {
|
|
echo json_encode(['success' => false, 'error' => 'Invalid mapping file: convert_csv function not found.']);
|
|
exit;
|
|
}
|
|
|
|
$inputTmpPath = $_FILES['fullInputFile']['tmp_name'];
|
|
$outputDir = __DIR__ . '/outputs';
|
|
if (!is_dir($outputDir)) {
|
|
mkdir($outputDir, 0775, true);
|
|
}
|
|
$outputFile = $outputDir . '/converted_' . time() . '.csv';
|
|
|
|
try {
|
|
convert_csv($inputTmpPath, $outputFile);
|
|
echo json_encode(['success' => true, 'download_url' => basename($outputFile)]);
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success' => false, 'error' => 'Error during conversion: ' . $e->getMessage()]);
|
|
}
|
|
exit;
|
|
}
|
|
|
|
|
|
echo json_encode(['success' => false, 'error' => 'No action specified.']); |