beginTransaction(); logStep(1, "Transaction started via beginTransaction()"); // --- 2. Recolección de Datos (Conductor + Coche) --- $phone = filterRequest("phone"); $password = filterRequest("password"); $firstName = filterRequest("first_name"); $lastName = filterRequest("last_name"); // تسجيل البيانات المبدئية (بدون كلمات المرور) للتأكد من وصولها logStep(2, "Inputs received -> Phone: $phone, Name: $firstName $lastName"); // التحقق من الحقول الإجبارية if (empty($phone) || empty($password) || empty($firstName) || empty($lastName)) { throw new Exception("Required fields missing (phone, password, first_name, last_name)."); } // --- 3. Generar ID de Conductor --- $driverId = substr(md5($phone), 0, 20); logStep(3, "Driver ID generated: $driverId"); // --- 4. Procesamiento de Datos del Conductor --- $password_hashed = password_hash($password, PASSWORD_DEFAULT); $email = filterRequest("email"); if (empty($email) || $email === 'Not specified') { $email = $phone . '@intaleqapp.com'; } $nameArabic = $firstName . ' ' . $lastName; $site = filterRequest("site"); $address = $site; // بيانات إضافية $gender = filterRequest("gender"); $license_type = filterRequest("license_type"); $nationalNumber = filterRequest("national_number"); $issue_date = filterRequest("issue_date"); $expiry_date = filterRequest("expiry_date"); $licenseCategories = filterRequest("license_categories"); $licenseIssueDate = filterRequest("license_issue_date"); $birthdate = filterRequest("birthdate"); $maritalStatus = filterRequest("maritalStatus"); // --- 5. Recolección de Datos del Coche --- $owner = filterRequest("owner"); $color = filterRequest("color"); $colorHex = filterRequest("color_hex"); $model = filterRequest("model"); $carPlate = filterRequest("car_plate"); $make = filterRequest("make"); $fuel = filterRequest("fuel"); $year = filterRequest("year"); $vin = filterRequest("vin"); if (empty($vin)) { $vin = 'unknown'; } $carExpirationDate = filterRequest("expiration_date"); logStep(4, "Data processing completed. Car Plate: $carPlate, VIN: $vin"); // --- 6. Cifrado de Datos --- try { $encryptedPhone = $encryptionHelper->encryptData($phone); $encryptedEmail = $encryptionHelper->encryptData($email); $encryptedFirstName = $encryptionHelper->encryptData($firstName); $encryptedLastName = $encryptionHelper->encryptData($lastName); $encryptedNameArabic = $encryptionHelper->encryptData($nameArabic); $encryptedGender = $encryptionHelper->encryptData($gender); $encryptedNationalNumber = $encryptionHelper->encryptData($nationalNumber); $encryptedAddress = $encryptionHelper->encryptData($address); $encryptedSite = $encryptionHelper->encryptData($site); $encryptedBirthdate = $encryptionHelper->encryptData($birthdate); $encryptedOwner = $encryptionHelper->encryptData($owner); $encryptedCarPlate = $encryptionHelper->encryptData($carPlate); logStep(5, "Encryption successful for sensitive fields."); } catch (Exception $encEx) { throw new Exception("Encryption Error: " . $encEx->getMessage()); } // --- 7. Comprobación de Duplicados --- // ملاحظة: إذا كان التشفير عشوائياً، فلن يجد التكرار هنا. $dup = $con->prepare("SELECT id FROM driver WHERE phone = :phone OR email = :email OR national_number = :national_number"); $dup->execute([':phone' => $encryptedPhone, ':email' => $encryptedEmail, ':national_number' =>$encryptedNationalNumber]); if ($dup->rowCount() > 0) { logStep(6, "Duplicate found! Phone or Email or encryptedNationalNumber already exists."); throw new Exception("Phone or email already registered."); } logStep(6, "No duplicates found. Proceeding."); // --- 8. INSERCIÓN 1: Tabla 'driver' --- $sqlDriver = " INSERT INTO driver ( id, phone, email, password, gender, license_type, national_number, name_arabic, issue_date, expiry_date, license_categories, address, licenseIssueDate, status, birthdate, site, first_name, last_name, accountBank, bankCode, employmentType, maritalStatus, fullNameMaritial, expirationDate, created_at, updated_at ) VALUES ( :id, :phone, :email, :pwd, :gender, :license_type, :national_number, :name_arabic, :issue_date, :expiry_date, :license_categories, :address, :licenseIssueDate, :status, :birthdate, :site, :first_name, :last_name, :accountBank, :bankCode, :employmentType, :maritalStatus, :fullNameMaritial, :expirationDate, NOW(), NOW() ) "; $stmtDriver = $con->prepare($sqlDriver); // تم توحيد المفاتيح لتشمل النقطتين (:) $driverData = [ ':id' => $driverId, ':phone' => $encryptedPhone, ':email' => $encryptedEmail, ':pwd' => $password_hashed, ':gender' => $encryptedGender, ':license_type' => $license_type, ':national_number' => $encryptedNationalNumber, ':name_arabic' => $encryptedNameArabic, ':issue_date' => $issue_date, ':expiry_date' => $expiry_date, ':license_categories' => $licenseCategories ?? 'B', ':address' => $encryptedAddress, ':licenseIssueDate' => $licenseIssueDate, ':status' => 'actives', ':birthdate' => $encryptedBirthdate, ':site' => $encryptedSite, ':first_name' => $encryptedFirstName, ':last_name' => $encryptedLastName, ':accountBank' => 'yet', ':bankCode' => 'yet', ':employmentType' => $maritalStatus ?? 'yet', ':maritalStatus' => $maritalStatus ?? 'yet', ':fullNameMaritial' => 'yet', ':expirationDate' => 'yet', ]; if (!$stmtDriver->execute($driverData)) { // تسجيل خطأ SQL بالتفصيل $errInfo = $stmtDriver->errorInfo(); throw new Exception("Driver Insert Failed: " . $errInfo[2]); } logStep(7, "Driver table insert successful."); // --- 9. INSERCIÓN 2: Tabla 'CarRegistration' --- $sqlCar = " INSERT INTO CarRegistration ( driverID, vin, owner, color, color_hex, model, car_plate, make, fuel, `year`, expiration_date, created_at ) VALUES ( :driverId, :vin, :owner, :color, :color_hex, :model, :car_plate, :make, :fuel, :year, :expiration_date, NOW() ) "; $stmtCar = $con->prepare($sqlCar); $carData = [ ':driverId' => $driverId, ':vin' => $vin, ':owner' => $encryptedOwner, ':color' => $color, ':color_hex' => $colorHex, ':model' => $model, ':car_plate' => $encryptedCarPlate, ':make' => $make, ':fuel' => $fuel, ':year' => $year, ':expiration_date' => $carExpirationDate ]; if (!$stmtCar->execute($carData)) { $errInfo = $stmtCar->errorInfo(); throw new Exception("Car Insert Failed: " . $errInfo[2]); } logStep(8, "CarRegistration insert successful."); // --- 10. Confirmar Transacción --- $con->commit(); logStep(9, "COMMIT successful. Sending Success Response."); jsonSuccess(["driverId" => $driverId, "message" => "Driver and car registered successfully."]); // --- 11. Enviar Notificación (خارج المعاملة يفضل، ولكن هنا كما في الكود الأصلي) --- try { $supportPhones = ['0952475740', '0952475742']; $randomIndex = array_rand($supportPhones); $phoneToUse = $supportPhones[$randomIndex]; $randomNumber = rand(1000, 999999); $messageBody = "أهلاً وسهلاً كابتن $firstName 👋\n" . "تم تفعيل حسابك على تطبيق *انطلق*.\n" . "يمكنك الآن تسجيل الدخول والبدء بالعمل مباشرة.\n" . "للمساعدة تواصل معنا على الرقم: $phoneToUse\n" . "نتمنى لك عمل موفق 🚖\n\n" . "معرف الرسالة: $randomNumber"; sendWhatsAppFromServer($phone, $messageBody); logStep(10, "WhatsApp notification sent."); } catch (Exception $waError) { // لا نوقف العملية إذا فشل الواتساب، فقط نسجل الخطأ logStep(10, "WhatsApp Warning: " . $waError->getMessage()); } } catch (PDOException $e) { $con->rollBack(); $errorMsg = "Database Error (PDO): " . $e->getMessage(); logStep("ERROR-PDO", $errorMsg); // إظهار رسالة عامة للمستخدم، وتسجيل التفاصيل في السيرفر jsonError("System error during registration. Please contact support."); } catch (Exception $e) { // إذا كانت المعاملة مفتوحة، قم بإلغائها if ($con->inTransaction()) { $con->rollBack(); } $errorMsg = "General Error: " . $e->getMessage(); logStep("ERROR-GEN", $errorMsg); jsonError($e->getMessage()); } ?>