false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8", ]; $pdo = new PDO($dsn, $dbUser, $dbPass, $options); // نجلب الحقول التي نحتاجها لبناء السر $sql = "SELECT id, phone, birthdate, national_number FROM driver"; $stmt = $pdo->query($sql); $update = $pdo->prepare("UPDATE driver SET password = :pwd WHERE id = :id"); $count = 0; $skipped = 0; $startTime = microtime(true); while ($row = $stmt->fetch()) { $id = $row['id']; $encPhone = $row['phone']; $encBirth = $row['birthdate'] ?? null; $encNat = $row['national_number'] ?? null; // نفك التشفير – قد يرجع null لو الحقل فاضي $phone = $encPhone ? $encryptionHelper->decryptData($encPhone) : null; $birth = $encBirth ? $encryptionHelper->decryptData($encBirth) : null; $nat = $encNat ? $encryptionHelper->decryptData($encNat) : null; if (empty($id) || empty($phone)) { // لو ناقصين، نتجاوز السطر مع تسجيل في اللوج error_log("[MIGRATE] Skip driver id={$id}: missing phone or id."); $skipped++; continue; } // في الوضع المثالي عندك nat + birthdate لكل السائقين // لو حاب تجبرهم يكونوا موجودين: /* if (empty($nat) || empty($birth)) { error_log("[MIGRATE] Skip driver id={$id}: missing nat or birthdate."); $skipped++; continue; } */ // phone مفروض يكون أصلاً مطبّع (9639...) من سكربت التسجيل $normalizedPhone = trim($phone); // نبني baseString: الأساس id + phone $parts = [$id, $normalizedPhone]; // نضيف رقم وطني أو سنة الميلاد (حسب الموجود) if (!empty($nat)) { $parts[] = trim($nat); } elseif (!empty($birth)) { // birthdate متوقعة بصيغة YYYY-01-01 -> نأخذ السنة فقط $year = substr($birth, 0, 4); if (preg_match('/^\d{4}$/', $year)) { $parts[] = $year; } } $baseString = implode('|', $parts); // اشتقاق السر النهائي (HEX string، بدون باينري) $hmacHex = hash_hmac('sha256', $baseString, $pepper, false); // نخزن فقط الهاش باستخدام password_hash $pwdHash = password_hash($hmacHex, PASSWORD_DEFAULT); $update->execute([ ':pwd' => $pwdHash, ':id' => $id, ]); $count++; // لوج بسيط كل 100 سائق if ($count % 100 === 0) { $elapsed = round(microtime(true) - $startTime, 2); error_log("[MIGRATE] Progress: updated {$count} drivers, skipped {$skipped}, elapsed {$elapsed}s"); } } $totalTime = round(microtime(true) - $startTime, 2); error_log("[MIGRATE] Done. Updated {$count} driver passwords, skipped {$skipped}. Total time: {$totalTime}s"); echo "Migration finished. Updated {$count} drivers, skipped {$skipped}. Time: {$totalTime}s\n"; } catch (PDOException $e) { error_log("[MIGRATE][PDO] " . $e->getMessage()); echo "Migration failed (DB error).\n"; exit(1); } catch (Exception $e) { error_log("[MIGRATE][GENERAL] " . $e->getMessage()); echo "Migration failed (general error).\n"; exit(1); }