35846-vm/chart.php
2025-11-19 12:47:09 +00:00

135 lines
4.4 KiB
PHP

<?php
header('Content-Type: application/json');
require_once __DIR__ . '/ai/LocalAIApi.php';
function return_error($message) {
echo json_encode(['success' => false, 'error' => $message]);
exit;
}
// 1. Get Request Data
$chartRequest = $_POST['chart_request'] ?? '';
$filePath = $_POST['file_path'] ?? '';
if (empty($chartRequest) || empty($filePath)) {
return_error('Missing chart request or file path.');
}
// Security check: ensure the file path is within the uploads directory
$uploadsDir = realpath(__DIR__ . '/uploads');
$realFilePath = realpath($filePath);
if (!$realFilePath || strpos($realFilePath, $uploadsDir) !== 0) {
return_error('Invalid file path provided.');
}
// 2. Read CSV Header and Sample Rows for context
$dataSample = '';
$handle = fopen($realFilePath, 'r');
if (!$handle) {
return_error('Failed to open the data file.');
}
$lineCount = 0;
$header = [];
while (($row = fgetcsv($handle)) !== false && $lineCount < 3) {
if ($lineCount === 0) {
$header = $row;
}
$dataSample .= implode(',', array_map(function($cell) {
return '"' . addslashes($cell) . '"';
}, $row)) . "\n";
$lineCount++;
}
fclose($handle);
if (empty($dataSample)) {
return_error('The data file appears to be empty.');
}
// 3. Prepare Prompt for AI to generate a PHP script
$prompt = <<<PROMPT
You are a PHP data processing expert. A user wants to create a chart.
Your task is to write a **complete PHP script** that reads a CSV file, processes it according to the user's request, and then **echoes a JSON object** formatted for the Chart.js library.
**User Request:** "{$chartRequest}"
**CSV File Path:** `{$realFilePath}`
**CSV Header:** `[" . implode('", "', $header) . "]`
**Data Sample:**
```csv
{$dataSample}
```
**Instructions for the script you generate:**
1. The script **MUST** be a complete, executable PHP script starting with `<?php`.
2. It must read the CSV file located at `{$realFilePath}`.
3. It must process the data to fit the user's request: `{$chartRequest}`.
4. It must support 'pie' and 'line' charts.
5. The **ONLY** output of the script must be a single JSON object.
6. The JSON object must have two keys: `"type"` (either `"pie"` or `"line"`) and `"data"` (the data structure for Chart.js).
**Chart.js Data Structure Examples:**
* **For a Pie Chart:**
`{"labels": ["Label 1", "Label 2"], "datasets": [{"data": [10, 20], "backgroundColor": ["#FF6384", "#36A2EB"]}]}`
* **For a Line Chart:**
`{"labels": ["Jan", "Feb"], "datasets": [{"label": "My Dataset", "data": [10, 20], "borderColor": "#FF6384", "fill": false}]}`
**IMPORTANT:** Do not include any text, explanation, or markdown formatting outside the `<?php ... ?>` block. The output must be ONLY the raw PHP code for the script.
PROMPT;
// 4. Call AI API
try {
$resp = LocalAIApi::createResponse(
[
'input' => [
['role' => 'system', 'content' => 'You are an expert PHP script generator for data visualization.'],
['role' => 'user', 'content' => $prompt],
],
]
);
if (empty($resp['success'])) {
return_error('AI API failed to generate the chart script.');
}
$aiCode = LocalAIApi::extractText($resp);
if (empty($aiCode)) {
return_error('AI returned an empty script.');
}
// Clean the AI response to get only the PHP code
$phpCode = $aiCode;
if (strpos($phpCode, '<?php') !== false) {
$phpCode = substr($phpCode, strpos($phpCode, '<?php'));
}
if (strpos($phpCode, '?>') !== false) {
$phpCode = substr($phpCode, 0, strpos($phpCode, '?>') + 2);
}
// 5. Execute the generated script and capture its output
$tempScriptPath = __DIR__ . '/uploads/generated_script_' . uniqid() . '.php';
file_put_contents($tempScriptPath, $phpCode);
ob_start();
include $tempScriptPath;
$chartJson = ob_get_clean();
unlink($tempScriptPath); // Clean up the script file
$chartData = json_decode($chartJson, true);
if (json_last_error() !== JSON_ERROR_NONE) {
error_log("Generated script output was not valid JSON: " . $chartJson);
return_error('The AI-generated script produced invalid data. Could not decode JSON.');
}
echo json_encode(['success' => true, 'chartData' => $chartData]);
} catch (Exception $e) {
error_log('Exception in chart generation: ' . $e->getMessage());
return_error('An unexpected error occurred while generating the chart.');
}