Files
zibo-dashboard/public/userarea/cad_area_process.php
T
2026-06-16 09:23:40 +02:00

339 lines
8.6 KiB
PHP

<?php
header('Content-Type: application/json; charset=utf-8');
require_once(__DIR__ . '/include/headscript.php');
function jsonResponse(array $data): void
{
echo json_encode($data);
exit;
}
function updateJobProcessing(PDO $pdo, int $id): void
{
$stmt = $pdo->prepare("
UPDATE cad_area_jobs
SET
status = 'processing',
message = 'Elaborazione in corso...',
updated_at = NOW()
WHERE id = ?
");
$stmt->execute([$id]);
}
function updateJobError(PDO $pdo, int $id, string $message, ?array $pythonResponse = null): void
{
$stmt = $pdo->prepare("
UPDATE cad_area_jobs
SET
status = 'error',
message = ?,
python_response = ?,
updated_at = NOW()
WHERE id = ?
");
$stmt->execute([
$message,
$pythonResponse ? json_encode($pythonResponse) : null,
$id
]);
}
function updateJobCompleted(PDO $pdo, int $id, array $response): void
{
$stmt = $pdo->prepare("
UPDATE cad_area_jobs
SET
status = 'completed',
message = ?,
area_mm2 = ?,
area_cm2 = ?,
area_m2 = ?,
width_mm = ?,
height_mm = ?,
scale_detected = ?,
scale_used = ?,
confidence = ?,
python_response = ?,
updated_at = NOW()
WHERE id = ?
");
$stmt->execute([
$response['message'] ?? 'Area calcolata correttamente.',
$response['area_mm2'] ?? null,
$response['area_cm2'] ?? null,
$response['area_m2'] ?? null,
$response['width_mm'] ?? null,
$response['height_mm'] ?? null,
$response['scale_detected'] ?? null,
$response['scale_used'] ?? null,
$response['confidence'] ?? null,
json_encode($response),
$id
]);
}
function normalizeCalculationMode(?string $mode): string
{
$allowed = [
'auto_roi',
'stitch_contour',
'filled_union',
'closed_path'
];
if (!$mode || !in_array($mode, $allowed, true)) {
return 'auto_roi';
}
return $mode;
}
function hasValidRoi(array $job): bool
{
return (
array_key_exists('roi_x', $job) &&
array_key_exists('roi_y', $job) &&
array_key_exists('roi_width', $job) &&
array_key_exists('roi_height', $job) &&
$job['roi_x'] !== null &&
$job['roi_y'] !== null &&
$job['roi_width'] !== null &&
$job['roi_height'] !== null &&
(float)$job['roi_width'] > 0 &&
(float)$job['roi_height'] > 0
);
}
function callPythonAreaService(string $url, array $job): array
{
$filePath = $job['file_path'] ?? '';
$originalFilename = $job['original_filename'] ?? basename($filePath);
if (!$filePath || !file_exists($filePath)) {
return [
'success' => false,
'message' => 'File PDF non trovato sul server: ' . $filePath
];
}
$mode = normalizeCalculationMode($job['calculation_mode'] ?? 'auto_roi');
$scaleRatio = $job['scale_used'] ?? null;
if ($scaleRatio === null || $scaleRatio === '' || (float)$scaleRatio <= 0) {
$scaleRatio = '1';
}
$curlFile = new CURLFile(
$filePath,
'application/pdf',
$originalFilename
);
$postFields = [
'file' => $curlFile,
'mode' => $mode,
'scale_ratio' => (string)$scaleRatio,
'roi_x' => (string)$job['roi_x'],
'roi_y' => (string)$job['roi_y'],
'roi_width' => (string)$job['roi_width'],
'roi_height' => (string)$job['roi_height'],
'roi_page' => (string)($job['roi_page'] ?? 1)
];
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $postFields,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 180,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_HTTPHEADER => [
'Accept: application/json'
]
]);
$rawResponse = curl_exec($ch);
$curlError = curl_error($ch);
$httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($rawResponse === false) {
return [
'success' => false,
'message' => 'Errore cURL verso Python: ' . $curlError
];
}
$decoded = json_decode($rawResponse, true);
if (!is_array($decoded)) {
return [
'success' => false,
'message' => 'Risposta Python non JSON valida.',
'http_code' => $httpCode,
'raw_response' => $rawResponse
];
}
if ($httpCode < 200 || $httpCode >= 300) {
return [
'success' => false,
'message' => $decoded['message'] ?? ('Servizio Python HTTP ' . $httpCode),
'http_code' => $httpCode,
'python_response' => $decoded,
'raw_response' => $rawResponse
];
}
return $decoded;
}
try {
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
$iduser = $iduserlogin ?? null;
$input = json_decode(file_get_contents('php://input'), true);
if (!is_array($input)) {
jsonResponse([
'success' => false,
'message' => 'Payload JSON non valido.'
]);
}
$ids = $input['ids'] ?? [];
if (!is_array($ids) || count($ids) === 0) {
jsonResponse([
'success' => false,
'message' => 'Nessun ID ricevuto.'
]);
}
$ids = array_values(array_unique(array_map('intval', $ids)));
$ids = array_filter($ids, fn($id) => $id > 0);
if (count($ids) === 0) {
jsonResponse([
'success' => false,
'message' => 'Nessun ID valido ricevuto.'
]);
}
$pythonServiceUrl = 'http://127.0.0.1:5055/calculate';
$results = [];
foreach ($ids as $id) {
if ($iduser === null || $iduser === '') {
$stmt = $pdo->prepare("
SELECT *
FROM cad_area_jobs
WHERE id = ?
LIMIT 1
");
$stmt->execute([$id]);
} else {
$stmt = $pdo->prepare("
SELECT *
FROM cad_area_jobs
WHERE id = ?
AND iduser = ?
LIMIT 1
");
$stmt->execute([$id, $iduser]);
}
$job = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$job) {
$results[] = [
'id' => $id,
'success' => false,
'message' => 'Record non trovato.'
];
continue;
}
if (!hasValidRoi($job)) {
$message = 'Prima devi definire la sezione da misurare tramite il pulsante Sezione.';
updateJobError($pdo, $id, $message, [
'success' => false,
'message' => $message,
'job_roi_debug' => [
'roi_x' => $job['roi_x'] ?? null,
'roi_y' => $job['roi_y'] ?? null,
'roi_width' => $job['roi_width'] ?? null,
'roi_height' => $job['roi_height'] ?? null,
'roi_page' => $job['roi_page'] ?? null,
'calculation_mode' => $job['calculation_mode'] ?? null
]
]);
$results[] = [
'id' => $id,
'success' => false,
'message' => $message
];
continue;
}
updateJobProcessing($pdo, $id);
$pythonResponse = callPythonAreaService($pythonServiceUrl, $job);
if (!($pythonResponse['success'] ?? false)) {
$message = $pythonResponse['message'] ?? 'Errore durante il calcolo Python.';
updateJobError($pdo, $id, $message, $pythonResponse);
$results[] = [
'id' => $id,
'success' => false,
'message' => $message,
'python_response' => $pythonResponse
];
continue;
}
updateJobCompleted($pdo, $id, $pythonResponse);
$results[] = [
'id' => $id,
'success' => true,
'message' => $pythonResponse['message'] ?? 'Area calcolata.',
'area_mm2' => $pythonResponse['area_mm2'] ?? null,
'area_cm2' => $pythonResponse['area_cm2'] ?? null
];
}
jsonResponse([
'success' => true,
'results' => $results
]);
} catch (Throwable $e) {
error_log('CAD area process error: ' . $e->getMessage());
jsonResponse([
'success' => false,
'message' => $e->getMessage()
]);
}