69 lines
3.5 KiB
PHP
69 lines
3.5 KiB
PHP
<?php
|
||
/**
|
||
* referral_code_helper.php — توليد كود الدعوة عند أول قراءة
|
||
* ─────────────────────────────────────────────────────────────
|
||
* سبب وجود هذا الملف عطل قائم: `get_unified_code.php` وحده يولّد الكود،
|
||
* وهو غير مُستدعى من أي شاشة في التطبيقين — الرابط معرّف في links.dart
|
||
* ولا أحد يناديه. بينما `get_driver_referrals.php` و
|
||
* `get_passenger_referrals.php` تقرآن فقط وتردّان null.
|
||
*
|
||
* النتيجة: صفّ لم يُكتب قط في `user_referral_codes`، فكود الدعوة null
|
||
* دائماً وشاشة الدعوة تدور بلا نهاية عند السائق والراكب معاً.
|
||
*
|
||
* الإصلاح هنا لا في التطبيق: القراءة نفسها تُنشئ الكود إن غاب. هذا
|
||
* يعالج التطبيقات المنشورة أصلاً بلا انتظار إصدار جديد.
|
||
*/
|
||
|
||
if (!function_exists('generateUnifiedCode')) {
|
||
function generateUnifiedCode(PDO $con): string
|
||
{
|
||
// حروف بلا I/O وأرقام بلا 0/1: الكود يُملى صوتياً بين السائقين.
|
||
for ($attempt = 0; $attempt < 20; $attempt++) {
|
||
$letters = substr(str_shuffle("ABCDEFGHJKLMNPQRSTUVWXYZ"), 0, 2);
|
||
$numbers = substr(str_shuffle("23456789"), 0, 4);
|
||
$code = $letters . $numbers;
|
||
|
||
$stmt = $con->prepare("SELECT COUNT(*) FROM user_referral_codes WHERE referral_code = ?");
|
||
$stmt->execute([$code]);
|
||
if ((int) $stmt->fetchColumn() === 0) {
|
||
return $code;
|
||
}
|
||
}
|
||
// احتياط: حلقة while اللانهائية الأصلية كانت تُعلّق العامل كاملاً
|
||
// لو امتلأت مساحة الأكواد. نسقط لكود أطول بدل التعليق.
|
||
return substr(strtoupper(bin2hex(random_bytes(4))), 0, 8);
|
||
}
|
||
}
|
||
|
||
if (!function_exists('ensureReferralCode')) {
|
||
/**
|
||
* يعيد كود الدعوة للمستخدم، ويُنشئه إن لم يكن موجوداً.
|
||
* يعيد null فقط إذا تعذّرت الكتابة (لا يُسقط الطلب).
|
||
*/
|
||
function ensureReferralCode(PDO $con, string $userId, string $userType): ?string
|
||
{
|
||
$stmt = $con->prepare("SELECT referral_code FROM user_referral_codes WHERE user_id = ? AND user_type = ?");
|
||
$stmt->execute([$userId, $userType]);
|
||
$existing = $stmt->fetchColumn();
|
||
if ($existing !== false && $existing !== null && $existing !== '') {
|
||
return (string) $existing;
|
||
}
|
||
|
||
try {
|
||
$newCode = generateUnifiedCode($con);
|
||
$con->prepare("INSERT INTO user_referral_codes (user_id, user_type, referral_code) VALUES (?, ?, ?)")
|
||
->execute([$userId, $userType, $newCode]);
|
||
return $newCode;
|
||
} catch (PDOException $e) {
|
||
// سباق بين طلبين متزامنين: الآخر كتب الصفّ أولاً — نقرأه.
|
||
$stmt->execute([$userId, $userType]);
|
||
$raced = $stmt->fetchColumn();
|
||
if ($raced !== false && $raced !== null && $raced !== '') {
|
||
return (string) $raced;
|
||
}
|
||
error_log("[referral_code_helper] " . $e->getMessage());
|
||
return null;
|
||
}
|
||
}
|
||
}
|