Update: 2026-06-12 01:23:54

This commit is contained in:
Hamza-Ayed
2026-06-12 01:23:54 +03:00
parent 7049c7468c
commit ef6b52d2e3
47 changed files with 1480 additions and 1472 deletions

View File

@@ -59,7 +59,9 @@ if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
exit;
}
$linkImage = 'https://intaleq.xyz/siro/Admin/adminUser/invoice_images/' . $new_filename;
$host = $_SERVER['HTTP_HOST'] ?? 'api.siromove.com';
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
$linkImage = "$protocol://$host/siro/Admin/adminUser/invoice_images/" . $new_filename;
error_log("[add_invoice.php] ✅ Image uploaded successfully: $linkImage");
}

View File

@@ -1,31 +1,48 @@
<?php
require_once __DIR__ . '/../connect.php';
// Get the image file from the request.
$image_file = $_FILES['image'];
header('Content-Type: application/json');
uploadLog("🚀 [EgyptDocuments/uploadEgyptIdBack.php] Egyptian ID back upload started.");
$driverID = filterRequest("driverID");
// Define allowed extensions
$allowed_extensions = ['jpg', 'jpeg', 'png'];
// Get the image file from the request.
$image_file = $_FILES['image'];
// Check if the image file was uploaded successfully.
if ($image_file['error'] !== UPLOAD_ERR_OK) {
echo "Image upload failed";
exit;
if (empty($driverID)) {
uploadLog("❌ Missing driverID parameter.", 'ERROR');
jsonError("driverID is required.");
exit;
}
if (isset($_FILES['image'])) {
uploadLog("$_FILES['image'] metadata", 'INFO', [
'name' => $_FILES['image']['name'] ?? 'unknown',
'type' => $_FILES['image']['type'] ?? 'unknown',
'size' => $_FILES['image']['size'] ?? 0,
'upload_error_code' => $_FILES['image']['error'] ?? UPLOAD_ERR_OK
]);
} else {
uploadLog("No 'image' file was sent in the request.", 'WARNING');
}
if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
$err = $_FILES['image']['error'] ?? 'missing_file';
uploadLog("❌ File upload validation failed. Code: $err", 'ERROR');
jsonError("Image upload failed");
exit;
}
$image_file = $_FILES['image'];
$allowed_extensions = ['jpg', 'jpeg', 'png'];
// Get file information
$image_name = $image_file['name'];
$image_size = $image_file['size'];
$image_extension = strtolower(pathinfo($image_name, PATHINFO_EXTENSION));
// Validate file extension
if (!in_array($image_extension, $allowed_extensions)) {
echo "Invalid image format";
exit;
if (!in_array($image_extension, $allowed_extensions, true)) {
uploadLog("Invalid image format extension: .$image_extension", 'ERROR');
jsonError("Invalid image format");
exit;
}
// Validate MIME type
@@ -34,38 +51,42 @@ $mime_type = finfo_file($finfo, $image_file['tmp_name']);
finfo_close($finfo);
$allowed_mime_types = ['image/jpeg', 'image/png', 'image/jpg'];
if (!in_array($mime_type, $allowed_mime_types)) {
echo "Invalid image format (MIME mismatch)";
exit;
if (!in_array($mime_type, $allowed_mime_types, true)) {
uploadLog("Invalid MIME type: $mime_type", 'ERROR');
jsonError("Invalid image format (MIME mismatch)");
exit;
}
// Generate a unique filename using timestamp and random string
// Generate a unique filename using driverID
$new_filename = $driverID . '.' . $image_extension;
// Set target directory for uploads
$target_dir = "card_image/";
$target_dir = __DIR__ . "/card_image/";
if (!is_dir($target_dir)) {
mkdir($target_dir, 0755, true);
}
// Construct target file path
$target_file = $target_dir . $new_filename;
// Move the image file to the target location
if (!move_uploaded_file($image_file['tmp_name'], $target_file)) {
echo json_encode(array('status' => "Failed to save image")); ;
exit;
uploadLog("Failed to save image to target file: $target_file", 'ERROR');
jsonError("Failed to save image");
exit;
}
// Store additional information (modify based on your needs)
$image_url = $target_dir . $new_filename; // Update if needed
$image_details = [
"name" => $image_name,
"size" => $image_size,
"extension" => $image_extension,
"url" => $image_url,
];
// Resolve dynamic URL
$host = $_SERVER['HTTP_HOST'] ?? 'api.siromove.com';
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
$image_url = "$protocol://$host/siro/EgyptDocuments/card_image/" . $new_filename;
// Use the image details for further processing (e.g., display, store in database)
// ...
echo json_encode(array('status' => 'Image uploaded successfully!'));
uploadLog("✅ Egypt ID back uploaded successfully. URL: $image_url");
printSuccess([
"status" => "success",
"url" => $image_url,
"file_link" => $image_url,
"image_url" => $image_url
]);
?>

View File

@@ -1,31 +1,48 @@
<?php
require_once __DIR__ . '/../connect.php';
// Get the image file from the request.
$image_file = $_FILES['image'];
header('Content-Type: application/json');
uploadLog("🚀 [EgyptDocuments/uploadEgyptidFront.php] Egyptian ID front upload started.");
$driverID = filterRequest("driverID");
// Define allowed extensions
$allowed_extensions = ['jpg', 'jpeg', 'png'];
// Get the image file from the request.
$image_file = $_FILES['image'];
// Check if the image file was uploaded successfully.
if ($image_file['error'] !== UPLOAD_ERR_OK) {
echo "Image upload failed";
exit;
if (empty($driverID)) {
uploadLog("❌ Missing driverID parameter.", 'ERROR');
jsonError("driverID is required.");
exit;
}
if (isset($_FILES['image'])) {
uploadLog("$_FILES['image'] metadata", 'INFO', [
'name' => $_FILES['image']['name'] ?? 'unknown',
'type' => $_FILES['image']['type'] ?? 'unknown',
'size' => $_FILES['image']['size'] ?? 0,
'upload_error_code' => $_FILES['image']['error'] ?? UPLOAD_ERR_OK
]);
} else {
uploadLog("No 'image' file was sent in the request.", 'WARNING');
}
if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
$err = $_FILES['image']['error'] ?? 'missing_file';
uploadLog("❌ File upload validation failed. Code: $err", 'ERROR');
jsonError("Image upload failed");
exit;
}
$image_file = $_FILES['image'];
$allowed_extensions = ['jpg', 'jpeg', 'png'];
// Get file information
$image_name = $image_file['name'];
$image_size = $image_file['size'];
$image_extension = strtolower(pathinfo($image_name, PATHINFO_EXTENSION));
// Validate file extension
if (!in_array($image_extension, $allowed_extensions)) {
echo "Invalid image format";
exit;
if (!in_array($image_extension, $allowed_extensions, true)) {
uploadLog("Invalid image format extension: .$image_extension", 'ERROR');
jsonError("Invalid image format");
exit;
}
// Validate MIME type
@@ -34,38 +51,42 @@ $mime_type = finfo_file($finfo, $image_file['tmp_name']);
finfo_close($finfo);
$allowed_mime_types = ['image/jpeg', 'image/png', 'image/jpg'];
if (!in_array($mime_type, $allowed_mime_types)) {
echo "Invalid image format (MIME mismatch)";
exit;
if (!in_array($mime_type, $allowed_mime_types, true)) {
uploadLog("Invalid MIME type: $mime_type", 'ERROR');
jsonError("Invalid image format (MIME mismatch)");
exit;
}
// Generate a unique filename using timestamp and random string
// Generate a unique filename using driverID
$new_filename = $driverID . '.' . $image_extension;
// Set target directory for uploads
$target_dir = "egypt/idFront/";
$target_dir = __DIR__ . "/egypt/idFront/";
if (!is_dir($target_dir)) {
mkdir($target_dir, 0755, true);
}
// Construct target file path
$target_file = $target_dir . $new_filename;
// Move the image file to the target location
if (!move_uploaded_file($image_file['tmp_name'], $target_file)) {
echo json_encode(array('status' => "Failed to save image")); ;
exit;
uploadLog("Failed to save image to target file: $target_file", 'ERROR');
jsonError("Failed to save image");
exit;
}
// Store additional information (modify based on your needs)
$image_url = $target_dir . $new_filename; // Update if needed
$image_details = [
"name" => $image_name,
"size" => $image_size,
"extension" => $image_extension,
"url" => $image_url,
];
// Resolve dynamic URL
$host = $_SERVER['HTTP_HOST'] ?? 'api.siromove.com';
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
$image_url = "$protocol://$host/siro/EgyptDocuments/egypt/idFront/" . $new_filename;
// Use the image details for further processing (e.g., display, store in database)
// ...
echo json_encode(array('status' => 'Image uploaded successfully!'));
uploadLog("✅ Egypt ID front uploaded successfully. URL: $image_url");
printSuccess([
"status" => "success",
"url" => $image_url,
"file_link" => $image_url,
"image_url" => $image_url
]);
?>

View File

@@ -46,7 +46,9 @@ if (!move_uploaded_file($file['tmp_name'], $uploadPath)) {
exit;
}
$imageUrl = "https://intaleq.xyz/siro/auth/uploads/documents/" . $uniqueName ;
$host = $_SERVER['HTTP_HOST'] ?? 'api-syria.siromove.com';
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
$imageUrl = "$protocol://$host/siro/auth/uploads/documents/" . $uniqueName ;
$imageData = file_get_contents($uploadPath);
$imageBase64 = base64_encode($imageData);
@@ -196,7 +198,7 @@ EOT
$prompt = $prompts[$type] ?? $prompts["id_front_sy"];
$apiKey = getenv("GEMINI_API_KEY");
$apiURL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-lite:generateContent?key=$apiKey";
$apiURL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-flash-lite-latest:generateContent?key=$apiKey";
$headers = ["Content-Type: application/json"];
$payload = [

View File

@@ -6,6 +6,8 @@
require_once __DIR__ . '/../../connect.php';
uploadLog("🚀 [uploadDocSyria.php] Document upload script started.");
$driverId = trim((string) filterRequest("driver_id"));
$type = trim((string) filterRequest("type"));
@@ -13,8 +15,23 @@ $type = trim((string) filterRequest("type"));
if ($driverId === "") { $driverId = "unknown"; }
if ($type === "") { $type = "generic"; }
uploadLog("📥 Request parameters: driver_id=$driverId, type=$type");
// ✅ التحقق من ملف الصورة
if (isset($_FILES['image'])) {
uploadLog("$_FILES['image'] metadata", 'INFO', [
'name' => $_FILES['image']['name'] ?? 'unknown',
'type' => $_FILES['image']['type'] ?? 'unknown',
'size' => $_FILES['image']['size'] ?? 0,
'upload_error_code' => $_FILES['image']['error'] ?? UPLOAD_ERR_OK
]);
} else {
uploadLog("No 'image' file was sent in the request.", 'WARNING');
}
if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) {
$err = $_FILES['image']['error'] ?? 'missing_file';
uploadLog("❌ File upload validation failed. Code: $err", 'ERROR');
error_log("Upload error: Image not provided or upload failed.");
jsonError("Image upload failed");
exit;
@@ -26,6 +43,7 @@ $file = $_FILES['image'];
$allowedExt = ['jpg', 'jpeg', 'png'];
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!in_array($extension, $allowedExt, true)) {
uploadLog("❌ Unsupported file extension: $extension", 'ERROR');
error_log("Unsupported file extension: $extension");
jsonError("Unsupported file type");
exit;
@@ -91,7 +109,7 @@ $publicPath = "/siro/auth/uploads/documents/" . $uniqueName;
$imageUrl = rtrim(BASE_URL, '/') . $publicPath;
// ✅ نتيجة نهائية: فقط رابط الصورة وبعض البيانات المفيدة
uploadLog("✅ Document upload succeeded. URL: $imageUrl");
printSuccess([
$imageUrl,
]);

View File

@@ -16,8 +16,9 @@ try {
exit;
}
/* ================== General Settings ================== */
$PUBLIC_BASE = "https://intaleq.xyz/driver_docs";
$host = $_SERVER['HTTP_HOST'] ?? 'api-syria.siromove.com';
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
$PUBLIC_BASE = "$protocol://$host/siro/auth/uploads/documents";
/* ================== 1) Input Fields ================== */
$raw_first_name = null;
@@ -38,8 +39,12 @@ try {
// vehicle_category_id, fuel_type_id
$docKeys = [
'driver_license_front',
'id_front',
'id_back',
'driver_license',
'driver_license_back',
'profile_picture',
'criminal_record',
'car_license_front',
'car_license_back'
];
@@ -63,6 +68,7 @@ try {
}
/* ================== 🟢 START PHONE FORMATTING LOGIC 🟢 ================== */
$country = 'Syria'; // Default
if (!empty($data['phone'])) {
$phone = $data['phone'];
@@ -70,39 +76,46 @@ try {
$phone = preg_replace('/[ \-\(\)\+]/', '', $phone);
$phone = trim($phone);
// 2. توحيد البادئات الدولية
if (strpos($phone, '00963') === 0) {
$phone = substr($phone, 2);
} elseif (strpos($phone, '0963') === 0) {
$phone = substr($phone, 1);
}
if (strpos($phone, '962') === 0 || strpos($phone, '00962') === 0) {
if (strpos($phone, '00962') === 0) $phone = substr($phone, 2);
$country = 'Jordan';
} elseif (strpos($phone, '20') === 0 || strpos($phone, '0020') === 0) {
if (strpos($phone, '0020') === 0) $phone = substr($phone, 2);
$country = 'Egypt';
} else {
// 2. توحيد البادئات الدولية (سوريا)
if (strpos($phone, '00963') === 0) {
$phone = substr($phone, 2);
} elseif (strpos($phone, '0963') === 0) {
$phone = substr($phone, 1);
}
// 3. معالجة الحالات الخاصة بالصفر الزائد بعد الرمز الدولي
if (strpos($phone, '96309') === 0) {
$phone = '9639' . substr($phone, 5);
}
elseif (strpos($phone, '9630') === 0) {
$phone = '9639' . substr($phone, 4);
}
// 3. معالجة الحالات الخاصة بالصفر الزائد بعد الرمز الدولي
if (strpos($phone, '96309') === 0) {
$phone = '9639' . substr($phone, 5);
}
elseif (strpos($phone, '9630') === 0) {
$phone = '9639' . substr($phone, 4);
}
// 4. معالجة الأرقام المحلية
elseif (strpos($phone, '09') === 0) {
$phone = '963' . substr($phone, 1);
}
elseif (strpos($phone, '9') === 0 && strlen($phone) == 9) {
$phone = '963' . $phone;
}
elseif (strpos($phone, '0') === 0 && strlen($phone) == 10) {
$phone = '963' . substr($phone, 1);
}
// 5. التأكد من وجود 9 بعد الرمز الدولي
if (strpos($phone, '963') === 0 && strlen($phone) > 3) {
if (strpos($phone, '9639') !== 0) {
$phone = '9639' . substr($phone, 3);
// 4. معالجة الأرقام المحلية
elseif (strpos($phone, '09') === 0) {
$phone = '963' . substr($phone, 1);
}
elseif (strpos($phone, '9') === 0 && strlen($phone) == 9) {
$phone = '963' . $phone;
}
elseif (strpos($phone, '0') === 0 && strlen($phone) == 10) {
$phone = '963' . substr($phone, 1);
}
// 5. التأكد من وجود 9 بعد الرمز الدولي
if (strpos($phone, '963') === 0 && strlen($phone) > 3) {
if (strpos($phone, '9639') !== 0) {
$phone = '9639' . substr($phone, 3);
}
}
}
$data['phone'] = $phone;
}
/* ================== 🔴 END PHONE FORMATTING LOGIC 🔴 ================== */
@@ -131,6 +144,7 @@ try {
$docUrls = [];
foreach ($docKeys as $k) {
$u = filterRequest($k);
if (($k === 'driver_license_back' || $k === 'criminal_record') && ($u === null || $u === '')) continue;
if ($u === null || $u === '') {
jsonError("Missing document URL: $k");
exit;
@@ -142,6 +156,149 @@ try {
$docUrls[$k] = $u;
}
/* ================== AI PROCESSING START ================== */
$apiKey = getenv("GEMINI_API_KEY");
if ($apiKey) {
$promptBase = '
You are a highly secure AI Assistant specialized in analyzing identification and driver documents.
Country Context: ' . ($country ?? 'Syria') . '
### TASK
We are providing you with multiple images representing a driver\'s documents (National ID, Driver License, Profile Picture, Criminal Record, and Car Registration).
Extract all the required data accurately according to the exact schema provided, and perform a FACE MATCHING analysis.
Since the driver may be from Jordan, Egypt, or Syria, the layout, fields, and distribution of information between the front and back of each card varies widely by country.
Therefore, do NOT assume a specific field is on the front or the back of a card. You must scan all provided document images (e.g., both ID images, both license images) and intelligently locate the requested fields wherever they appear on the cards.
### RULES
1. Convert any Eastern-Arabic digits (٠١٢٣٤٥٦٧٨٩) to Western digits (0-9).
2. Dates must be formatted as ISO `YYYY-MM-DD`.
3. Smart Extraction: Scan all provided document images without restriction. Do not fail the overall request if some optional fields (like governorate or address or issue dates) are missing or unreadable on the card. Simply set those specific fields to `null` in the JSON, but do NOT set the overall status to failure. Overall status should only be \'failure\' if there is a critical security/authenticity issue (e.g., face mismatch, fake/forged documents, or missing primary driver identity).
4. FACE MATCHING (CRITICAL): Compare the face in the "Profile Picture" with the photos on the "National ID" and "Driver License".
5. Ensure the Criminal/Non-Conviction record is valid and matches the driver\'s name.
6. The `national_number` and `vin` (chassis) must contain Latin digits/characters only.
7. Normalize color names (e.g. "أبيض" -> "White") and provide a matching Hex code (e.g. "#FFFFFF").
8. Do NOT add markdown formatting around the output. Return ONLY raw JSON.
### REQUIRED JSON OUTPUT FORMAT
{
"status": "success|failure",
"reason": "If failure, state the reason (e.g., Face mismatch, blurry, invalid record)",
"face_match_confidence": "high|low",
"driver": {
"full_name": "", // Full name in Arabic
"national_number": "", // National ID/National number (Latin digits)
"dob": "YYYY-MM-DD", // Date of birth
"address": "", // Full address
"governorate": "", // Governorate/Site/City
"gender": "Male|Female", // Gender
"id_issue_date": "YYYY-MM-DD", // National ID issue date
"license_issue_date": "YYYY-MM-DD", // Driver license issue date
"license_expiry_date": "YYYY-MM-DD", // Driver license expiry date
"license_number": "", // Driver license number
"license_category": "", // License category (e.g., D1, B, Private, Public)
"blood_type": "", // Blood type (e.g., A+, O-)
"civil_registry": "", // Civil registry/Place of registration
"birth_place": "" // Place of birth
},
"car": {
"car_plate": "", // Full car plate (e.g., 155186 درعا)
"owner": "", // Owner full name
"vin": "", // Chassis/VIN number
"color": "", // Color name
"color_hex": "", // Color hex code (e.g., #FFFFFF)
"car_issue_date": "YYYY-MM-DD", // Car registration issue date
"inspection_date": "YYYY-MM-DD", // Car next inspection date
"make": "", // Car Make (e.g., Hyundai)
"model": "", // Car Model (e.g., H1)
"year": "", // Manufacturing year (e.g., 2019)
"fuel": "" // Fuel type (e.g., Petrol, Diesel, Electric)
}
}';
$contents = [
["role" => "user", "parts" => [["text" => $promptBase]]]
];
foreach ($docUrls as $key => $url) {
$imgData = @file_get_contents($url);
if ($imgData !== false) {
$base64 = base64_encode($imgData);
$ext = strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION));
$mime = ($ext === 'png') ? 'image/png' : 'image/jpeg';
$contents[0]["parts"][] = ["text" => "Image type: " . $key];
$contents[0]["parts"][] = ["inlineData" => ["mimeType" => $mime, "data" => $base64]];
}
}
$apiURL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-flash-lite-latest:generateContent?key=$apiKey";
$payload = ["contents" => $contents];
$ch = curl_init($apiURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
$response = curl_exec($ch);
curl_close($ch);
if ($response) {
$aiData = json_decode($response, true);
$textRaw = $aiData['candidates'][0]['content']['parts'][0]['text'] ?? '';
$textRaw = trim(preg_replace('/```json|```/', '', $textRaw));
$json = json_decode($textRaw, true);
if ($json && isset($json['status']) && strtolower($json['status']) === 'failure') {
jsonError("AI Verification Failed: " . ($json['reason'] ?? 'Unknown reason'));
exit;
}
if ($json && isset($json['driver'])) {
$ex = $json['driver'];
if (!empty($ex['full_name'])) {
$data['name_arabic'] = $ex['full_name'];
$parts = explode(' ', trim($ex['full_name']));
if (count($parts) >= 2) {
$data['first_name'] = $parts[0];
$data['last_name'] = implode(' ', array_slice($parts, 1));
} else {
$data['first_name'] = $ex['full_name'];
$data['last_name'] = '';
}
}
if (!empty($ex['national_number'])) $data['national_number'] = $ex['national_number'];
if (!empty($ex['dob'])) {
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $ex['dob'])) {
$data['birthdate'] = $ex['dob'];
} elseif (preg_match('/^\d{4}$/', $ex['dob'])) {
$data['birthdate'] = $ex['dob'] . '-01-01';
}
}
if (!empty($ex['address'])) $data['address'] = $ex['address'];
if (!empty($ex['governorate'])) $data['site'] = $ex['governorate'];
if (!empty($ex['gender'])) $data['gender'] = $ex['gender'];
if (!empty($ex['id_issue_date'])) $data['issue_date'] = $ex['id_issue_date'];
if (!empty($ex['license_issue_date'])) $data['licenseIssueDate'] = $ex['license_issue_date'];
if (!empty($ex['license_expiry_date'])) $data['expiry_date'] = $ex['license_expiry_date'];
if (!empty($ex['license_category'])) $data['license_categories'] = $ex['license_category'];
// Not mapped directly in basic DB schema but extracted: blood_type, civil_registry, birth_place
}
if ($json && isset($json['car'])) {
$ex = $json['car'];
if (!empty($ex['car_plate'])) $car['car_plate'] = $ex['car_plate'];
if (!empty($ex['make'])) $car['make'] = $ex['make'];
if (!empty($ex['model'])) $car['model'] = $ex['model'];
if (!empty($ex['year'])) $car['year'] = $ex['year'];
if (!empty($ex['color'])) $car['color'] = $ex['color'];
if (!empty($ex['color_hex'])) $car['color_hex'] = $ex['color_hex'];
if (!empty($ex['vin'])) $car['vin'] = $ex['vin'];
if (!empty($ex['owner'])) $car['owner'] = $ex['owner'];
if (!empty($ex['fuel'])) $car['fuel'] = $ex['fuel'];
}
}
}
/* ================== AI PROCESSING END ================== */
/* ================== 2) Generate default id/email ================== */
if (empty($data['id'])) {
$data['id'] = 'DRV' . date('YmdHis') . random_int(1000, 9999);
@@ -320,6 +477,7 @@ $pwdHashed = password_hash($rawSecret, PASSWORD_DEFAULT);
");
foreach ($docKeys as $k) {
if (!isset($docUrls[$k])) continue;
$url = $docUrls[$k];
$name = basename(parse_url($url, PHP_URL_PATH) ?? '');
if ($name === '') { $name = $k . '_' . time() . '.jpg'; }
@@ -330,6 +488,18 @@ $pwdHashed = password_hash($rawSecret, PASSWORD_DEFAULT);
':image_name' => $name,
':link' => $url,
]);
if ($k === 'profile_picture') {
$insProfile = $con->prepare("
INSERT INTO imageProfileCaptain (driverID, image_name, link)
VALUES (:driverID, :image_name, :link)
");
$insProfile->execute([
':driverID' => $driverID,
':image_name' => $name,
':link' => $url,
]);
}
}
/* ================== 10) Commit ================== */

View File

@@ -10,12 +10,17 @@ const MAX_FILE_MB = 5;
const ALLOWED_MIMES = ['image/jpeg','image/png','image/webp']; // فقط صور
const UPLOAD_ROOT = __DIR__ . "/../../private_uploads"; // مجلد خاص (غير عام)
const SIGN_SECRET = getenv('SECRET_KEY_HMAC'); // غيّرها واقرأها من .env
const PUBLIC_BASE = 'https://syria.intaleq.xyz/siro'; // الدومين العلني
$host = $_SERVER['HTTP_HOST'] ?? 'api-syria.siromove.com';
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
define('PUBLIC_BASE', "$protocol://$host/siro");
const SIGNED_TTL_SEC = 172800; // 2 days = 60*60*24
// أنشئ مجلد الرفع إن لم يكن موجودًا
if (!is_dir(UPLOAD_ROOT)) { @mkdir(UPLOAD_ROOT, 0700, true); }
// Log entry
uploadLog("🚀 [uploadSyrianDocs.php] Document upload script started.");
// (اختياري) هيدرز أمان
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
$hmacHeader = $_SERVER['HTTP_X_HMAC_AUTH'] ?? '';
@@ -26,7 +31,10 @@ $driverId = filterRequest('driver_id');
$docType = filterRequest('doc_type');
$purpose = filterRequest('purpose'); // اختياري
uploadLog("📥 Request params: driver_id=$driverId, doc_type=$docType");
if (empty($driverId) || empty($docType)) {
uploadLog("❌ Missing driver_id or doc_type params.", 'ERROR');
jsonError("driver_id and doc_type are required.");
exit;
}
@@ -39,12 +47,26 @@ $allowedDocTypes = [
'car_license_back',
];
if (!in_array($docType, $allowedDocTypes, true)) {
uploadLog("❌ Invalid doc_type value: $docType", 'ERROR');
jsonError("Invalid doc_type.");
exit;
}
// --------- التحقق من الملف ---------
if (isset($_FILES['file'])) {
uploadLog("$_FILES['file'] metadata", 'INFO', [
'name' => $_FILES['file']['name'] ?? 'unknown',
'type' => $_FILES['file']['type'] ?? 'unknown',
'size' => $_FILES['file']['size'] ?? 0,
'upload_error_code' => $_FILES['file']['error'] ?? UPLOAD_ERR_OK
]);
} else {
uploadLog("No 'file' payload was sent in the request.", 'WARNING');
}
if (!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
$err = $_FILES['file']['error'] ?? 'missing_file';
uploadLog("❌ File upload validation failed. Code: $err", 'ERROR');
jsonError("No file uploaded or upload error.");
exit;
}
@@ -116,6 +138,7 @@ $fileUrl = PUBLIC_BASE . "/secure_image.php"
. "&signature={$signature}";
// --------- استجابة ---------
uploadLog("✅ Document upload succeeded. URL: $fileUrl");
printSuccess([
"status" => "success",
"success_file" => true,

View File

@@ -172,6 +172,42 @@ function appLog(string $message, string $level = 'INFO'): void
@error_log($entry . PHP_EOL, 3, $logDir . '/app.log');
}
function uploadLog(string $message, string $level = 'INFO', array $context = []): void
{
$logDir = __DIR__ . '/../logs';
if (!is_dir($logDir)) {
@mkdir($logDir, 0777, true);
}
if (!isset($context['ip'])) {
$context['ip'] = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
}
if (!isset($context['user_agent'])) {
$context['user_agent'] = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
}
if (isset($context['upload_error_code'])) {
$errCode = $context['upload_error_code'];
$context['upload_error_desc'] = match ($errCode) {
UPLOAD_ERR_OK => 'UPLOAD_ERR_OK (0): No error, file uploaded successfully.',
UPLOAD_ERR_INI_SIZE => 'UPLOAD_ERR_INI_SIZE (1): The uploaded file exceeds the upload_max_filesize directive in php.ini.',
UPLOAD_ERR_FORM_SIZE => 'UPLOAD_ERR_FORM_SIZE (2): The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
UPLOAD_ERR_PARTIAL => 'UPLOAD_ERR_PARTIAL (3): The uploaded file was only partially uploaded (common on weak/3G networks).',
UPLOAD_ERR_NO_FILE => 'UPLOAD_ERR_NO_FILE (4): No file was uploaded.',
UPLOAD_ERR_NO_TMP_DIR => 'UPLOAD_ERR_NO_TMP_DIR (6): Missing a temporary folder.',
UPLOAD_ERR_CANT_WRITE => 'UPLOAD_ERR_CANT_WRITE (7): Failed to write file to disk.',
UPLOAD_ERR_EXTENSION => 'UPLOAD_ERR_EXTENSION (8): A PHP extension stopped the file upload.',
default => "Unknown upload error code: $errCode",
};
}
$entry = date('Y-m-d H:i:s') . " [$level] " . $message;
if ($context) {
$entry .= ' | ' . json_encode($context, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
@error_log($entry . PHP_EOL, 3, $logDir . '/upload.log');
}
function debugLog(string $message): void
{
appLog($message, 'DEBUG');

View File

@@ -4,15 +4,31 @@ require_once __DIR__ . '/../../functions.php';
header('Content-Type: application/json');
uploadLog("🚀 [ride/card-image-driver/add.php] Card image upload started.");
try {
$con = Database::get('main');
} catch (Exception $e) {
uploadLog("❌ DB Connection failed: " . $e->getMessage(), 'ERROR');
http_response_code(500);
echo json_encode(['status' => 'Database connection failed.']);
exit;
}
if (isset($_FILES['image'])) {
uploadLog("$_FILES['image'] metadata", 'INFO', [
'name' => $_FILES['image']['name'] ?? 'unknown',
'type' => $_FILES['image']['type'] ?? 'unknown',
'size' => $_FILES['image']['size'] ?? 0,
'upload_error_code' => $_FILES['image']['error'] ?? UPLOAD_ERR_OK
]);
} else {
uploadLog("No 'image' file was sent in request.", 'WARNING');
}
if (!isset($_FILES['image']) || $_FILES['image']['error'] != UPLOAD_ERR_OK) {
$err = $_FILES['image']['error'] ?? 'missing_file';
uploadLog("❌ File upload validation failed. Code: $err", 'ERROR');
echo json_encode(['status' => 'The image file was not uploaded successfully.']);
exit;
}
@@ -21,6 +37,7 @@ $image_file = $_FILES['image'];
$driverID = filterRequest("driver_id");
if (empty($driverID)) {
uploadLog("❌ Missing driver_id parameter.", 'ERROR');
echo json_encode(['status' => 'Missing driver ID.']);
exit;
}
@@ -58,7 +75,9 @@ if (!move_uploaded_file($image_file['tmp_name'], $target_file)) {
exit;
}
$linlImage = 'https://ride.mobile-app.store/card_image/' . $new_filename;
$host = $_SERVER['HTTP_HOST'] ?? 'ride.mobile-app.store';
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
$linlImage = "$protocol://$host/siro/card_image/" . $new_filename;
try {
// استخدام Prepared Statements للحماية من الحقن (SQL Injection)
@@ -73,6 +92,7 @@ try {
':driver_id' => $driverID
]);
uploadLog("✅ Card image updated successfully for driver_id: $driverID, URL: $linlImage");
echo json_encode(['status' => 'Record updated successfully']);
} else {
$insertStmt = $con->prepare("INSERT INTO card_images (id, driver_id, image_name, link) VALUES (SHA2(UUID(), 256), :driver_id, :image_name, :link)");
@@ -82,9 +102,11 @@ try {
':link' => $linlImage
]);
uploadLog("✅ Card image inserted successfully for driver_id: $driverID, URL: $linlImage");
echo json_encode(['status' => 'Record inserted successfully']);
}
} catch (PDOException $e) {
uploadLog("❌ Database error: " . $e->getMessage(), 'ERROR');
error_log("Database Error in card-image-driver/add.php: " . $e->getMessage());
echo json_encode(['status' => 'Database operation failed.']);
}

View File

@@ -6,17 +6,30 @@
require_once __DIR__ . '/connect.php'; // يفترض أنه يستدعي core/bootstrap.php
appLog("🚀 [upload_profile_image.php] بدأ تنفيذ سكربت رفع الصورة");
uploadLog("🚀 [uploadImagePortrate.php] Profile image upload script execution started.");
try {
// Check if $_FILES has errors
if (isset($_FILES['image'])) {
uploadLog("$_FILES['image'] metadata", 'INFO', [
'name' => $_FILES['image']['name'] ?? 'unknown',
'type' => $_FILES['image']['type'] ?? 'unknown',
'size' => $_FILES['image']['size'] ?? 0,
'upload_error_code' => $_FILES['image']['error'] ?? UPLOAD_ERR_OK
]);
} else {
uploadLog("No 'image' file was sent in the request.", 'WARNING');
}
// 1. Rate Limiting للرفع
$limiter = new RateLimiter($redis);
$limiter->enforce(RateLimiter::identifier($user_id ?? null), 'upload');
$driverID = filterRequest("driverID");
appLog("📥 Received driverID: $driverID");
uploadLog("📥 Received driverID: $driverID");
if (empty($driverID)) {
uploadLog("❌ Driver ID is missing.", 'ERROR');
jsonError('Driver ID is required.', 400);
}
@@ -25,16 +38,18 @@ try {
$uploadResult = uploadImageSecure('image', $target_dir, $driverID);
if (!$uploadResult['success']) {
uploadLog("❌ Image upload failed", 'ERROR', ['driverID' => $driverID, 'error' => $uploadResult['error']]);
securityLog("❌ Image upload failed", ['driverID' => $driverID, 'error' => $uploadResult['error']]);
jsonError($uploadResult['error'], 400);
}
$new_filename = $uploadResult['filename'];
appLog("✅ File moved successfully to: " . $uploadResult['path']);
uploadLog("✅ File moved successfully to: " . $uploadResult['path']);
// 3. تحديث قاعدة البيانات
$linkImage = 'https://api.intaleq.xyz/siro_v3/portrate_captain_image/' . $new_filename;
$uploadDate = date("Y-m-d H:i:s");
// 3. تحديث قاعدة البيانات ديناميكياً
$host = $_SERVER['HTTP_HOST'] ?? 'api.siromove.com';
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
$linkImage = "$protocol://$host/siro/portrate_captain_image/" . $new_filename;
// تأكد من أن الاتصال قادم من connect.php أو اجلبه
$con = Database::get('main');
@@ -48,7 +63,6 @@ try {
// تحديث
$updateSQL = "UPDATE imageProfileCaptain SET image_name = ?, link = ? WHERE driverID = ?";
$updateStmt = $con->prepare($updateSQL);
// Note: imageProfileCaptain doesn't seem to have 'upload_date' in the original insert, but let's check if we should add it. Let's just update image_name and link as in the insert statement.
$success = $updateStmt->execute([$new_filename, $linkImage, $driverID]);
} else {
// إدخال جديد
@@ -58,10 +72,10 @@ try {
}
if ($success) {
appLog("✅ Record updated for driverID: $driverID");
uploadLog("✅ Record updated for driverID: $driverID, Link: $linkImage");
jsonSuccess(['file_link' => $linkImage], 'Record updated successfully.');
} else {
appLog("❌ Failed to update DB record for driverID: $driverID");
uploadLog("❌ Failed to update DB record for driverID: $driverID", 'ERROR');
jsonError('Failed to update record.', 500);
}

View File

@@ -51,8 +51,10 @@ if (!move_uploaded_file($audio_file['tmp_name'], $target_file)) {
exit;
}
// Construct the link to the uploaded audio file
$base_url = 'https://api.intaleq.xyz/siro_v3/upload_audio/'; // Updated to match Siro V3
// Construct the link to the uploaded audio file dynamically
$host = $_SERVER['HTTP_HOST'] ?? 'api.siromove.com';
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
$base_url = "$protocol://$host/siro/upload_audio/";
$linkAudio = $base_url . $new_filename;