339 lines
8.6 KiB
PHP
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()
|
|
]);
|
|
}
|