- Implemented a comprehensive PHP script to seed the database with test data for users, doctors, clinics, appointments, payments, ratings, comments, and blogs. - Included functions for generating random data such as UUIDs, mobile numbers, and images. - Downloaded and stored images for doctors and clinics using parallel curl requests. - Inserted static data for insurances, patients, and doctors with various attributes including specialties and services. - Ensured data integrity by disabling foreign key checks during the seeding process and re-enabling them afterward. - Provided a summary of the total records inserted into each table at the end of the script.
483 lines
27 KiB
PHP
483 lines
27 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
$pdo = new PDO('mysql:host=db;dbname=db;charset=utf8mb4', 'db', 'db');
|
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
$pdo->exec('SET NAMES utf8mb4');
|
|
$pdo->exec('SET FOREIGN_KEY_CHECKS = 0');
|
|
|
|
$now = time();
|
|
|
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
function uuid(): string {
|
|
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
|
|
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff),
|
|
mt_rand(0, 0x0fff) | 0x4000, mt_rand(0, 0x3fff) | 0x8000,
|
|
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff));
|
|
}
|
|
function rand_item(array $arr) { return $arr[array_rand($arr)]; }
|
|
function rand_items(array $arr, int $min, int $max): array {
|
|
$count = rand($min, $max);
|
|
$keys = (array) array_rand($arr, min($count, count($arr)));
|
|
return array_map(fn($k) => $arr[$k], $keys);
|
|
}
|
|
function mobile(): string {
|
|
$prefix = rand_item(['0910','0911','0912','0913','0914','0915','0916','0917','0918','0919',
|
|
'0930','0933','0935','0936','0937','0938','0939','0901','0902','0903',
|
|
'0920','0921','0922','0991','0992','0993','0994']);
|
|
return $prefix . str_pad((string)rand(1000000, 9999999), 7, '0', STR_PAD_LEFT);
|
|
}
|
|
function nationalCode(): string {
|
|
return str_pad((string)rand(1000000000, 9999999999), 10, '0', STR_PAD_LEFT);
|
|
}
|
|
function medicalCode(): string {
|
|
return (string)rand(10000000, 99999999);
|
|
}
|
|
function passwordHash(): string {
|
|
return '$2y$13$' . substr(base64_encode(random_bytes(32)), 0, 53);
|
|
}
|
|
|
|
// ── Static data ───────────────────────────────────────────────────────────────
|
|
$maleNames = ['علی','محمد','حسین','احمد','رضا','مهدی','حسن','اکبر','ابراهیم','کریم',
|
|
'جواد','امیر','سعید','مجید','فرید','کامران','سیاوش','داریوش','پرویز','شهرام',
|
|
'بهرام','فرهاد','نادر','مسعود','وحید','یاسر','حامد','سجاد','ایمان','میثم',
|
|
'آرش','آرمان','آرمین','پدرام','پویا','کیان','سیروس','بابک','فریبرز','هوشنگ'];
|
|
$femaleNames = ['فاطمه','زهرا','مریم','سارا','نرگس','لیلا','نازنین','مهناز','شیرین','پروین',
|
|
'ملیحه','الناز','آتنا','باران','ترانه','دلارام','رویا','شادی','گلناز','ماهرخ',
|
|
'ندا','نیلوفر','هانیه','یاسمن','زینب','حدیثه','سمیه','طاهره','عاطفه','منیژه'];
|
|
$lastNames = ['احمدی','محمدی','رضایی','حسینی','موسوی','جعفری','کریمی','نوری','صادقی','قاسمی',
|
|
'عباسی','میرزایی','رحیمی','اکبری','یوسفی','حیدری','طاهری','نصیری','سلیمانی','زارعی',
|
|
'مرادی','شریفی','منصوری','ذبیحی','تهرانی','اصفهانی','مشهدی','شیرازی','تبریزی','همدانی',
|
|
'ملکی','درویشی','امیری','نجفی','شاهی','بهرامی','خسروی','گلمحمدی','فدایی','ولیپور',
|
|
'نظری','فروزان','پورعلی','دهقانی','صالحی','ربیعی','مجیدی','سبحانی','زمانی','بهشتی'];
|
|
$degrees = ['متخصص','فوق تخصص','دکترای عمومی','فلوشیپ','استادیار','دانشیار','پروفسور'];
|
|
$genders = ['male','female'];
|
|
$bios = [
|
|
'دارای بیش از ۱۵ سال سابقه در حوزه تخصصی خود، عضو انجمن پزشکی ایران.',
|
|
'فارغالتحصیل دانشگاه علوم پزشکی تهران، دارای تجربه کار در بیمارستانهای معتبر.',
|
|
'متخصص با سابقه درخشان در درمان بیماران، ارائه خدمات با بالاترین کیفیت.',
|
|
'عضو هیئت علمی دانشگاه و مشاور پزشکی با بیش از ۱۰ سال تجربه بالینی.',
|
|
'دارای گواهینامههای تخصصی از مراکز بینالمللی، آشنا با جدیدترین روشهای درمانی.',
|
|
'پزشک باتجربه با رویکرد جامع در درمان، اعتقاد به طب پیشگیری و توانبخشی.',
|
|
'متعهد به ارائه بهترین مراقبتهای پزشکی با رعایت اصول اخلاق پزشکی.',
|
|
'دارای مدرک تخصصی از اروپا، تجربه کار در مراکز درمانی پیشرفته.',
|
|
];
|
|
$clinicNames = ['کلینیک تخصصی','مرکز درمانی','بیمارستان','کلینیک جامع','مرکز مشاوره پزشکی',
|
|
'مطب دکتر','کلینیک ویژه','مرکز پزشکی','درمانگاه','کلینیک سلامت'];
|
|
$clinicSuffixes = ['امید','نوین','رازی','ابن سینا','سینا','شفا','سلامت','آریا','پارس','ایران','مهر','صبا'];
|
|
$appointmentStatuses = ['reserved','visited','completed','cancelled_by_user','cancelled_by_doctor','no_show'];
|
|
$appointmentStatusWeights = [30,25,25,10,5,5]; // percent chance
|
|
$paymentStatuses = ['paid','pending','failed'];
|
|
$commentTexts = [
|
|
'دکتر بسیار خوب و دلسوزی هستند. توضیحات کاملی دادند.',
|
|
'معاینه دقیق بود و تشخیص درست. ممنونم.',
|
|
'وقت انتظار کمی داشتم، دکتر سر وقت حاضر بود.',
|
|
'بسیار متبحر و با حوصله. مشکلم کاملاً حل شد.',
|
|
'توصیه میکنم. رفتار بسیار حرفهای دارند.',
|
|
'دکتر خوبی هستند ولی وقت ویزیت کمی کوتاه بود.',
|
|
'راضی بودم از ویزیت. درمان موثر بود.',
|
|
'یکی از بهترین دکترهایی که به آنها مراجعه کردهام.',
|
|
'کمی منتظر ماندم ولی ارزشش را داشت.',
|
|
'متخصص واقعی در حوزه کارشان. توصیه میکنم.',
|
|
];
|
|
$blogTitles = [
|
|
'راهنمای جامع برای پیشگیری از بیماریهای قلبی',
|
|
'تغذیه سالم برای کودکان در سنین رشد',
|
|
'اهمیت چکاپ منظم سالانه',
|
|
'راهکارهای مقابله با استرس و اضطراب',
|
|
'علائم هشداردهنده دیابت نوع ۲',
|
|
'ورزش و تأثیر آن بر سلامت قلب و عروق',
|
|
'خواب کافی و نقش آن در سلامت جسم و روان',
|
|
'راهنمای مراقبت از پوست در فصول مختلف',
|
|
'پیشگیری از پوکی استخوان با تغذیه مناسب',
|
|
'نکات مهم برای مراقبت از بینایی',
|
|
'سرطان پستان؛ تشخیص زودهنگام نجاتبخش است',
|
|
'بهداشت دهان و دندان در کودکان',
|
|
'فشار خون بالا و روشهای کنترل آن',
|
|
'نقش واکسیناسیون در پیشگیری از بیماریها',
|
|
'آرتروز زانو؛ علائم، پیشگیری و درمان',
|
|
];
|
|
$blogBodies = [
|
|
'بیماریهای قلبی از مهمترین علل مرگ در ایران و جهان هستند. با رعایت سبک زندگی سالم، ترک دخانیات و فعالیت بدنی منظم میتوان خطر آن را کاهش داد.',
|
|
'تغذیه متعادل و سرشار از ویتامینها برای رشد کودکان ضروری است. مصرف میوه، سبزیجات، پروتئین و لبنیات را در برنامه غذایی کودک خود بگنجانید.',
|
|
'انجام آزمایشهای منظم، بررسی فشار خون، قند خون و چکاپ کلی هر سال توصیه میشود. تشخیص زودهنگام بیماریها درمان را آسانتر میکند.',
|
|
'مدیریت استرس با تکنیکهای تنفس عمیق، مدیتیشن و فعالیت بدنی امکانپذیر است. در صورت نیاز از مشاور یا روانپزشک کمک بگیرید.',
|
|
'دیابت نوع ۲ با علائمی مانند تشنگی زیاد، ادرار مکرر و خستگی مزمن همراه است. کنترل وزن و رژیم غذایی مناسب در پیشگیری از آن نقش دارد.',
|
|
];
|
|
|
|
// ── Load existing data ────────────────────────────────────────────────────────
|
|
$provinces = $pdo->query('SELECT id FROM provinces')->fetchAll(PDO::FETCH_COLUMN);
|
|
$cities = $pdo->query('SELECT id, province_id FROM cities WHERE id != 600')->fetchAll(PDO::FETCH_ASSOC);
|
|
$cityIds = array_column($cities, 'id');
|
|
$specialtyParents = $pdo->query('SELECT id FROM specialties WHERE parent_id IS NULL')->fetchAll(PDO::FETCH_COLUMN);
|
|
$allSpecialties = $pdo->query('SELECT id FROM specialties')->fetchAll(PDO::FETCH_COLUMN);
|
|
$allServices = $pdo->query('SELECT id, specialty_id FROM doctor_services')->fetchAll(PDO::FETCH_ASSOC);
|
|
$serviceIds = array_column($allServices, 'id');
|
|
|
|
// Build specialty->services map
|
|
$specialtyServicesMap = [];
|
|
foreach ($allServices as $svc) {
|
|
if ($svc['specialty_id']) {
|
|
$specialtyServicesMap[$svc['specialty_id']][] = $svc['id'];
|
|
}
|
|
}
|
|
|
|
$count = 0;
|
|
|
|
// ── 1. Insurances ─────────────────────────────────────────────────────────────
|
|
echo "Inserting insurances...\n";
|
|
$basicInsurances = [
|
|
['تأمین اجتماعی','basic'],['خدمات درمانی','basic'],['نیروهای مسلح','basic'],
|
|
['کمیته امداد','basic'],['بهزیستی','basic'],['روستایی','basic'],
|
|
];
|
|
$suppInsurances = [
|
|
['ایران','supplementary'],['آسیا','supplementary'],['البرز','supplementary'],
|
|
['پارسیان','supplementary'],['سامان','supplementary'],['میهن','supplementary'],
|
|
['دانا','supplementary'],['رازی','supplementary'],['کوثر','supplementary'],['معلم','supplementary'],
|
|
];
|
|
$insStmt = $pdo->prepare('INSERT IGNORE INTO insurances (uuid,name,type,status) VALUES (?,?,?,1)');
|
|
$insIds = [];
|
|
foreach (array_merge($basicInsurances, $suppInsurances) as $ins) {
|
|
$insStmt->execute([uuid(), $ins[0], $ins[1]]);
|
|
$insIds[] = $pdo->lastInsertId();
|
|
$count++;
|
|
}
|
|
$insIds = array_filter($insIds); // remove zeros from IGNORE
|
|
if (empty($insIds)) {
|
|
$insIds = $pdo->query('SELECT id FROM insurances')->fetchAll(PDO::FETCH_COLUMN);
|
|
}
|
|
echo " Insurances: " . count($insIds) . "\n";
|
|
|
|
// ── 2. Users (patients) ───────────────────────────────────────────────────────
|
|
echo "Inserting users (patients)...\n";
|
|
$usedMobiles = [];
|
|
$patientIds = [];
|
|
$uStmt = $pdo->prepare(
|
|
'INSERT INTO users (uuid,mobile_number,password_hash,email,real_name,roles,status,created_at,updated_at)
|
|
VALUES (?,?,?,?,?,?,1,?,?)'
|
|
);
|
|
for ($i = 0; $i < 200; $i++) {
|
|
$gender = rand_item($genders);
|
|
$firstName = $gender === 'male' ? rand_item($maleNames) : rand_item($femaleNames);
|
|
$lastName = rand_item($lastNames);
|
|
$name = $firstName . ' ' . $lastName;
|
|
do { $mobile = mobile(); } while (isset($usedMobiles[$mobile]));
|
|
$usedMobiles[$mobile] = true;
|
|
$email = strtolower(rand_item(['user','p','pt','patient'])) . $i . '@example.ir';
|
|
$ts = $now - rand(86400, 86400 * 365);
|
|
$uStmt->execute([uuid(), $mobile, passwordHash(), $email, $name, '["ROLE_USER"]', $ts, $ts]);
|
|
$patientIds[] = (int)$pdo->lastInsertId();
|
|
$count++;
|
|
}
|
|
echo " Patients: " . count($patientIds) . "\n";
|
|
|
|
// ── 3. Doctor users ───────────────────────────────────────────────────────────
|
|
echo "Inserting doctors...\n";
|
|
$doctorUserIds = [];
|
|
$doctorIds = [];
|
|
$duStmt = $pdo->prepare(
|
|
'INSERT INTO users (uuid,mobile_number,password_hash,email,real_name,roles,status,created_at,updated_at)
|
|
VALUES (?,?,?,?,?,?,1,?,?)'
|
|
);
|
|
$dStmt = $pdo->prepare(
|
|
'INSERT INTO doctors (uuid,name,gender,medical_system_code,mobile_number,activity_time,degree,info,
|
|
images,doctor_rate,doctor_rate_percentage,active_doctor_appointment,created_at,updated_at,user_id)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,1,?,?,?)'
|
|
);
|
|
for ($i = 0; $i < 60; $i++) {
|
|
$gender = $i % 4 === 0 ? 'female' : 'male';
|
|
$firstName = $gender === 'male' ? rand_item($maleNames) : rand_item($femaleNames);
|
|
$lastName = rand_item($lastNames);
|
|
$name = 'دکتر ' . $firstName . ' ' . $lastName;
|
|
do { $mobile = mobile(); } while (isset($usedMobiles[$mobile]));
|
|
$usedMobiles[$mobile] = true;
|
|
$email = 'dr' . $i . '@clinic-pro.ir';
|
|
$ts = $now - rand(86400 * 30, 86400 * 730);
|
|
$duStmt->execute([uuid(), $mobile, passwordHash(), $email, $name, '["ROLE_USER","ROLE_DOCTOR"]', $ts, $ts]);
|
|
$userId = (int)$pdo->lastInsertId();
|
|
$doctorUserIds[] = $userId;
|
|
$rate = round(rand(35, 50) / 10, 1);
|
|
$ratePct = rand(72, 98);
|
|
$dStmt->execute([
|
|
uuid(), $name, $gender, medicalCode(), $mobile,
|
|
rand(5, 25), rand_item($degrees), rand_item($bios),
|
|
json_encode([]), $rate, $ratePct, $ts, $ts, $userId
|
|
]);
|
|
$doctorIds[] = (int)$pdo->lastInsertId();
|
|
$count += 2;
|
|
}
|
|
echo " Doctors: " . count($doctorIds) . "\n";
|
|
|
|
// ── 4. Doctor specialties & services ─────────────────────────────────────────
|
|
echo "Linking doctor specialties/services...\n";
|
|
$dsStmt = $pdo->prepare('INSERT IGNORE INTO doctor_specialties (doctor_id,specialty_id) VALUES (?,?)');
|
|
$deStmt = $pdo->prepare('INSERT IGNORE INTO doctor_expertise (doctor_id,service_id) VALUES (?,?)');
|
|
$dpStmt = $pdo->prepare('INSERT IGNORE INTO doctor_provinces (doctor_id,province_id) VALUES (?,?)');
|
|
$dcStmt = $pdo->prepare('INSERT IGNORE INTO doctor_cities (doctor_id,city_id) VALUES (?,?)');
|
|
$daStmt = $pdo->prepare(
|
|
'INSERT INTO doctor_addresses (uuid,name,address,telephone,latitude,longitude,created_at,updated_at,doctor_id,city_id,province_id)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?)'
|
|
);
|
|
|
|
$cityProvinceMap = array_column($cities, 'province_id', 'id');
|
|
$streetNames = ['خیابان ولیعصر','خیابان انقلاب','خیابان آزادی','بلوار کشاورز','خیابان شریعتی',
|
|
'خیابان مطهری','خیابان فردوسی','خیابان پاسداران','خیابان جمهوری','خیابان امام خمینی'];
|
|
$buildingDescs = ['ساختمان پزشکان','برج طبی','مجتمع پزشکی','کلینیک ویژه','مطب','مرکز درمانی'];
|
|
|
|
foreach ($doctorIds as $idx => $doctorId) {
|
|
// 1-2 specialties per doctor
|
|
$numSpec = rand(1, 2);
|
|
$chosenParents = (array)array_rand(array_flip($specialtyParents), min($numSpec, count($specialtyParents)));
|
|
foreach ($chosenParents as $specId) {
|
|
$dsStmt->execute([$doctorId, $specId]);
|
|
$count++;
|
|
// Add 2-5 child specialties under same parent if exist
|
|
$children = array_values(array_filter($allSpecialties, fn($s) => !in_array($s, $specialtyParents)));
|
|
foreach (array_slice($children, 0, rand(2, 5)) as $cs) {
|
|
$dsStmt->execute([$doctorId, $cs]);
|
|
$count++;
|
|
}
|
|
// Services for this specialty
|
|
$svcPool = $specialtyServicesMap[$specId] ?? array_slice($serviceIds, 0, 10);
|
|
foreach (rand_items($svcPool, 3, 8) as $svcId) {
|
|
$deStmt->execute([$doctorId, $svcId]);
|
|
$count++;
|
|
}
|
|
}
|
|
|
|
// 1-3 cities per doctor
|
|
$chosenCities = rand_items($cityIds, 1, 3);
|
|
foreach ($chosenCities as $cityId) {
|
|
$provId = $cityProvinceMap[$cityId] ?? null;
|
|
$dcStmt->execute([$doctorId, $cityId]);
|
|
if ($provId) $dpStmt->execute([$doctorId, $provId]);
|
|
$count += $provId ? 2 : 1;
|
|
|
|
// Doctor address for each city
|
|
$street = rand_item($streetNames);
|
|
$building = rand_item($buildingDescs);
|
|
$no = rand(1, 200);
|
|
$address = 'تهران، ' . $street . '، پلاک ' . $no . '، ' . $building;
|
|
$lat = 33.0 + (rand(0, 700) / 100);
|
|
$lon = 48.0 + (rand(0, 1500) / 100);
|
|
$tel = '0' . rand_item(['21','511','411','31','71','81','351','44']) . rand(10000000, 99999999);
|
|
$ts = $now - rand(86400, 86400 * 180);
|
|
$daStmt->execute([uuid(), 'مطب شماره ' . ($idx+1), $address, $tel, $lat, $lon, $ts, $ts, $doctorId, $cityId, $provId]);
|
|
$count++;
|
|
}
|
|
}
|
|
|
|
// ── 5. Clinics ────────────────────────────────────────────────────────────────
|
|
echo "Inserting clinics...\n";
|
|
$clinicIds = [];
|
|
$clStmt = $pdo->prepare(
|
|
'INSERT INTO clinics (uuid,name,info,address,telephone,is_24_7,working_days,latitude,longitude,
|
|
city_id,province_id,images_clinic,clinic_logo,created_at,updated_at,user_id)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'
|
|
);
|
|
$clDStmt = $pdo->prepare('INSERT IGNORE INTO clinic_doctors (clinic_id,doctor_id) VALUES (?,?)');
|
|
$clSpStmt = $pdo->prepare('INSERT IGNORE INTO clinic_specialties (clinic_id,specialty_id) VALUES (?,?)');
|
|
$clSvStmt = $pdo->prepare('INSERT IGNORE INTO clinic_services (clinic_id,service_id) VALUES (?,?)');
|
|
$clInStmt = $pdo->prepare('INSERT IGNORE INTO clinic_insurances (clinic_id,insurance_id) VALUES (?,?)');
|
|
|
|
$workingDays = ['شنبه تا چهارشنبه ۸ تا ۲۰','شنبه تا پنجشنبه ۸ تا ۱۸','یکشنبه تا پنجشنبه ۹ تا ۱۷',
|
|
'شنبه تا سهشنبه ۷ تا ۱۹','همه روزه ۸ تا ۲۲','شنبه تا چهارشنبه ۹ تا ۲۰'];
|
|
|
|
$shuffledDoctors = $doctorIds;
|
|
shuffle($shuffledDoctors);
|
|
|
|
for ($i = 0; $i < 30; $i++) {
|
|
$cityRow = rand_item($cities);
|
|
$cityId = (int)$cityRow['id'];
|
|
$provId = (int)$cityRow['province_id'];
|
|
$lat = 33.0 + (rand(0, 700) / 100);
|
|
$lon = 48.0 + (rand(0, 1500) / 100);
|
|
$is247 = rand(0, 5) === 0 ? 1 : 0;
|
|
$name = rand_item($clinicNames) . ' ' . rand_item($clinicSuffixes);
|
|
$ts = $now - rand(86400 * 30, 86400 * 365);
|
|
$tel = '0' . rand_item(['21','511','411','31','71','81','351','44']) . rand(10000000, 99999999);
|
|
$address = rand_item($streetNames) . '، پلاک ' . rand(1,300);
|
|
$ownerId = $doctorUserIds[array_rand($doctorUserIds)];
|
|
$clStmt->execute([
|
|
uuid(), $name, 'ارائه خدمات تخصصی پزشکی با استفاده از جدیدترین تجهیزات.',
|
|
$address, $tel, $is247, rand_item($workingDays), $lat, $lon,
|
|
$cityId, $provId, json_encode([]), json_encode([]), $ts, $ts, $ownerId
|
|
]);
|
|
$clinicId = (int)$pdo->lastInsertId();
|
|
$clinicIds[] = $clinicId;
|
|
$count++;
|
|
|
|
// 2-4 doctors per clinic
|
|
$cDocs = array_splice($shuffledDoctors, 0, rand(2, 4));
|
|
if (empty($cDocs)) $cDocs = rand_items($doctorIds, 2, 3);
|
|
foreach ($cDocs as $dId) {
|
|
$clDStmt->execute([$clinicId, $dId]); $count++;
|
|
}
|
|
// 2-4 specialties
|
|
foreach (rand_items($specialtyParents, 2, 4) as $spId) {
|
|
$clSpStmt->execute([$clinicId, $spId]); $count++;
|
|
}
|
|
// 3-6 services
|
|
foreach (rand_items($serviceIds, 3, 6) as $svId) {
|
|
$clSvStmt->execute([$clinicId, $svId]); $count++;
|
|
}
|
|
// 3-6 insurances
|
|
foreach (rand_items($insIds, 3, 6) as $inId) {
|
|
$clInStmt->execute([$clinicId, $inId]); $count++;
|
|
}
|
|
}
|
|
echo " Clinics: " . count($clinicIds) . "\n";
|
|
|
|
// ── 6. Appointments ───────────────────────────────────────────────────────────
|
|
echo "Inserting appointments...\n";
|
|
$apptStmt = $pdo->prepare(
|
|
'INSERT INTO appointments (uuid,slot_start,slot_end,status,note,created_at,updated_at,doctor_id,user_id)
|
|
VALUES (?,?,?,?,?,?,?,?,?)'
|
|
);
|
|
$apptIds = [];
|
|
$apptStatusFinal = [];
|
|
|
|
// weighted random status
|
|
function weightedStatus(array $statuses, array $weights): string {
|
|
$total = array_sum($weights);
|
|
$r = rand(1, $total);
|
|
$cum = 0;
|
|
foreach ($statuses as $i => $status) {
|
|
$cum += $weights[$i];
|
|
if ($r <= $cum) return $status;
|
|
}
|
|
return $statuses[0];
|
|
}
|
|
|
|
$appointmentStatuses = ['reserved','visited','completed','cancelled_by_user','cancelled_by_doctor','no_show'];
|
|
$apptWeights = [20, 25, 30, 10, 8, 7];
|
|
|
|
for ($i = 0; $i < 500; $i++) {
|
|
$doctorId = rand_item($doctorIds);
|
|
$userId = rand_item($patientIds);
|
|
$status = weightedStatus($appointmentStatuses, $apptWeights);
|
|
|
|
// Past appointments: visited/completed/cancelled, Future: reserved
|
|
if (in_array($status, ['visited','completed','no_show','cancelled_by_user','cancelled_by_doctor'])) {
|
|
$slotStart = $now - rand(3600, 86400 * 180);
|
|
} else {
|
|
$slotStart = $now + rand(3600, 86400 * 30);
|
|
}
|
|
$slotEnd = $slotStart + 1800; // 30 min
|
|
$ts = $slotStart - rand(3600, 86400 * 7);
|
|
$notes = ['','مراجعه اول','پیگیری','نوبت اضطراری','مشاوره','کنترل دورهای'];
|
|
$apptStmt->execute([uuid(), $slotStart, $slotEnd, $status, rand_item($notes), $ts, $ts, $doctorId, $userId]);
|
|
$apptId = (int)$pdo->lastInsertId();
|
|
$apptIds[] = $apptId;
|
|
$apptStatusFinal[] = $status;
|
|
$count++;
|
|
}
|
|
echo " Appointments: " . count($apptIds) . "\n";
|
|
|
|
// ── 7. Payments ───────────────────────────────────────────────────────────────
|
|
echo "Inserting payments...\n";
|
|
$payStmt = $pdo->prepare(
|
|
'INSERT INTO payments (uuid,order_id,amount_rials,status,gateway,type,reference_id,created_at,updated_at,user_id,appointment_id)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?,?)'
|
|
);
|
|
$gateways = ['mellat','sep','zarinpal','parsian'];
|
|
// Only completed/visited appointments get paid
|
|
$paidApptIds = [];
|
|
foreach ($apptIds as $k => $apptId) {
|
|
if (in_array($apptStatusFinal[$k], ['visited','completed','reserved'])) {
|
|
$paidApptIds[] = [$apptId, $k];
|
|
}
|
|
}
|
|
shuffle($paidApptIds);
|
|
$paidApptIds = array_slice($paidApptIds, 0, 380);
|
|
|
|
foreach ($paidApptIds as [$apptId, $k]) {
|
|
$status = in_array($apptStatusFinal[$k], ['visited','completed']) ? 'paid' : rand_item(['paid','pending']);
|
|
$amount = rand_item([1500000,2000000,2500000,3000000,3500000,4000000,4500000,5000000]);
|
|
$userId = rand_item($patientIds);
|
|
$ts = $now - rand(3600, 86400 * 180);
|
|
$refId = $status === 'paid' ? (string)rand(100000000, 999999999) : null;
|
|
$payStmt->execute([
|
|
uuid(), 'ORD-' . strtoupper(substr(uuid(), 0, 8)), $amount, $status,
|
|
rand_item($gateways), 'appointment', $refId, $ts, $ts, $userId, $apptId
|
|
]);
|
|
$count++;
|
|
}
|
|
echo " Payments: " . count($paidApptIds) . "\n";
|
|
|
|
// ── 8. Rates ──────────────────────────────────────────────────────────────────
|
|
echo "Inserting rates...\n";
|
|
$rateStmt = $pdo->prepare('INSERT INTO rates (uuid,score,created_at,updated_at,user_id,doctor_id) VALUES (?,?,?,?,?,?)');
|
|
$usedRatePairs = [];
|
|
$rateCount = 0;
|
|
$i = 0;
|
|
while ($rateCount < 200 && $i < 1000) {
|
|
$i++;
|
|
$doctorId = rand_item($doctorIds);
|
|
$userId = rand_item($patientIds);
|
|
$key = "$userId-$doctorId";
|
|
if (isset($usedRatePairs[$key])) continue;
|
|
$usedRatePairs[$key] = true;
|
|
$score = rand_item([1,2,3,3,4,4,4,5,5,5]);
|
|
$ts = $now - rand(3600, 86400 * 300);
|
|
$rateStmt->execute([uuid(), $score, $ts, $ts, $userId, $doctorId]);
|
|
$rateCount++;
|
|
$count++;
|
|
}
|
|
echo " Rates: $rateCount\n";
|
|
|
|
// ── 9. Comments ───────────────────────────────────────────────────────────────
|
|
echo "Inserting comments...\n";
|
|
$comStmt = $pdo->prepare('INSERT INTO comments (uuid,body,status,created_at,updated_at,user_id,doctor_id) VALUES (?,?,?,?,?,?,?)');
|
|
$comStatuses = ['approved','approved','approved','pending','rejected'];
|
|
for ($i = 0; $i < 150; $i++) {
|
|
$doctorId = rand_item($doctorIds);
|
|
$userId = rand_item($patientIds);
|
|
$ts = $now - rand(3600, 86400 * 300);
|
|
$comStmt->execute([uuid(), rand_item($commentTexts), rand_item($comStatuses), $ts, $ts, $userId, $doctorId]);
|
|
$count++;
|
|
}
|
|
echo " Comments: 150\n";
|
|
|
|
// ── 10. Blogs ─────────────────────────────────────────────────────────────────
|
|
echo "Inserting blogs...\n";
|
|
$blogStmt = $pdo->prepare(
|
|
'INSERT INTO blogs (uuid,title,slug,body,summary,tags,status,created_at,updated_at,author_id)
|
|
VALUES (?,?,?,?,?,?,?,?,?,?)'
|
|
);
|
|
$adminUserId = null;
|
|
$adminRow = $pdo->query("SELECT id FROM users WHERE roles LIKE '%ROLE_ADMIN%' LIMIT 1")->fetch(PDO::FETCH_ASSOC);
|
|
if ($adminRow) $adminUserId = $adminRow['id'];
|
|
|
|
$blogTags = [['سلامت','قلب'],['کودکان','تغذیه'],['پیشگیری','چکاپ'],['روانشناسی','استرس'],
|
|
['دیابت','تغذیه'],['ورزش','قلب'],['خواب','سلامت'],['پوست','مراقبت'],
|
|
['استخوان','تغذیه'],['چشم','بینایی'],['سرطان','پیشگیری'],['دندان','بهداشت'],
|
|
['فشار خون','قلب'],['واکسن','پیشگیری'],['مفصل','ارتوپدی']];
|
|
$usedSlugs = [];
|
|
for ($i = 0; $i < min(count($blogTitles), 15); $i++) {
|
|
$title = $blogTitles[$i];
|
|
$slug = 'blog-post-' . ($i + 1) . '-' . rand(1000, 9999);
|
|
$body = rand_item($blogBodies) . ' ' . rand_item($blogBodies);
|
|
$tags = json_encode($blogTags[$i] ?? ['سلامت'], JSON_UNESCAPED_UNICODE);
|
|
$status = $i < 12 ? 'published' : 'draft';
|
|
$ts = $now - rand(86400, 86400 * 200);
|
|
$authorId = $adminUserId ?? rand_item($doctorUserIds);
|
|
$blogStmt->execute([uuid(), $title, $slug, $body, mb_substr($body, 0, 150), $tags, $status, $ts, $ts, $authorId]);
|
|
$count++;
|
|
}
|
|
echo " Blogs: 15\n";
|
|
|
|
$pdo->exec('SET FOREIGN_KEY_CHECKS = 1');
|
|
|
|
echo "\n=== Seed Complete ===\n";
|
|
$tables = ['users','doctors','clinics','clinic_doctors','doctor_specialties','doctor_expertise',
|
|
'doctor_provinces','doctor_cities','doctor_addresses','appointments','payments',
|
|
'rates','comments','blogs','insurances'];
|
|
$total = 0;
|
|
foreach ($tables as $t) {
|
|
$c = (int)$pdo->query("SELECT COUNT(*) FROM `$t`")->fetchColumn();
|
|
echo " $t: $c\n";
|
|
$total += $c;
|
|
}
|
|
echo "\nTotal records across tables: $total\n";
|