PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES=>false, ]); }catch(Throwable $e){ http_response_code(500); echo json_encode(['error'=>'فشل الاتصال بقاعدة البيانات — تحقق من البيانات في أعلى api.php'],JF); exit; } /* ---------- [3] إنشاء الجداول تلقائياً (أول تشغيل فقط) ---------- */ $pdo->exec("CREATE TABLE IF NOT EXISTS users( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, pass_hash VARCHAR(255) NOT NULL, salt VARCHAR(64) NOT NULL DEFAULT '', name VARCHAR(100) NOT NULL, role ENUM('admin','employee') NOT NULL DEFAULT 'employee', job VARCHAR(80) DEFAULT 'مبيعات', phone VARCHAR(20) DEFAULT '', active TINYINT(1) DEFAULT 1 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); $pdo->exec("CREATE TABLE IF NOT EXISTS leads( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(150) NOT NULL, phone VARCHAR(20) NOT NULL UNIQUE, agent_id INT NULL, status ENUM('new','follow','booked','off') NOT NULL DEFAULT 'new', note TEXT, added_on DATE NOT NULL, last_contact DATE NULL, due_date DATE NULL, INDEX idx_agent(agent_id), INDEX idx_status(status), INDEX idx_added(added_on) ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); $pdo->exec("CREATE TABLE IF NOT EXISTS activity_log( id INT AUTO_INCREMENT PRIMARY KEY, at BIGINT NOT NULL, actor VARCHAR(100), action VARCHAR(500) NOT NULL ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); $pdo->exec("CREATE TABLE IF NOT EXISTS settings( skey VARCHAR(50) PRIMARY KEY, svalue TEXT ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); $pdo->exec("CREATE TABLE IF NOT EXISTS tokens( token VARCHAR(64) PRIMARY KEY, user_id INT NOT NULL, expires BIGINT NOT NULL, INDEX idx_user(user_id) ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); /* ---------- [4] أدوات ---------- */ function settingGet($pdo,$k,$d=null){ $s=$pdo->prepare('SELECT svalue FROM settings WHERE skey=?'); $s->execute([$k]); $r=$s->fetch(); if(!$r) return $d; $v=json_decode($r['svalue'],true); return ($v===null && $r['svalue']!=='null') ? $r['svalue'] : $v; } function settingSet($pdo,$k,$v){ $s=$pdo->prepare('INSERT INTO settings(skey,svalue) VALUES(?,?) ON DUPLICATE KEY UPDATE svalue=VALUES(svalue)'); $s->execute([$k,json_encode($v,JF)]); } function bump($pdo){ settingSet($pdo,'v',(int)settingGet($pdo,'v',0)+1); } function addLog($pdo,$actor,$action){ $s=$pdo->prepare('INSERT INTO activity_log(at,actor,action) VALUES(?,?,?)'); $s->execute([round(microtime(true)*1000),$actor,$action]); } function dBack($n){ return date('Y-m-d',strtotime("$n day")); } function todayS(){ return date('Y-m-d'); } /* ---------- [5] التهيئة التلقائية ---------- */ function ensureSeed($pdo){ $c=$pdo->query('SELECT COUNT(*) c FROM users')->fetch()['c']; if((int)$c===0){ $ins=$pdo->prepare('INSERT INTO users(username,pass_hash,salt,name,role,job,phone,active) VALUES(?,?,?,?,?,?,?,1)'); $ins->execute(['admin',password_hash('admin123',PASSWORD_DEFAULT),'','مدير النظام','admin','إدارة','01000000000']); $ins->execute(['mahmoud',password_hash('123456',PASSWORD_DEFAULT),'','محمود سعيد','employee','مبيعات أول','01001112233']); $ins->execute(['sara',password_hash('123456',PASSWORD_DEFAULT),'','سارة عبد الله','employee','مبيعات','01004445566']); $ins->execute(['ahmed',password_hash('123456',PASSWORD_DEFAULT),'','أحمد شوقي','employee','مبيعات','01007778899']); $ins->execute(['mona',password_hash('123456',PASSWORD_DEFAULT),'','منى إبراهيم','employee','مبيعات','01012223344']); $ids=[]; foreach($pdo->query('SELECT id,username FROM users') as $r) $ids[$r['username']]=$r['id']; $il=$pdo->prepare('INSERT INTO leads(name,phone,agent_id,status,note,added_on,last_contact,due_date) VALUES(?,?,?,?,?,?,?,?)'); $il->execute(['أحمد محمود','01012345671',$ids['mahmoud'],'new','مهتم بمشروع الواحات السكنية',dBack(3),null,null]); $il->execute(['ياسمين فؤاد','01012345672',$ids['mahmoud'],'follow','طلب معاينة يوم الخميس',dBack(4),dBack(0),dBack(0)]); $il->execute(['كريم عادل','01012345673',$ids['sara'],'booked','وافق على الدفعة الأولى',dBack(6),dBack(1),null]); $il->execute(['نور الهدى','01012345674',$ids['sara'],'follow','ينتظر رد الزوجة',dBack(5),dBack(-1),dBack(-1)]); $il->execute(['مصطفى سيد','01012345675',$ids['ahmed'],'new','',dBack(2),null,null]); $il->execute(['هبة سمير','01012345676',$ids['ahmed'],'off','السعر أعلى من الميزانية',dBack(7),dBack(3),null]); $il->execute(['عمر خالد','01012345677',$ids['mona'],'follow','يرجى الاتصال بعد الخامسة مساءً',dBack(2),dBack(0),dBack(0)]); $il->execute(['دينا رمضان','01012345678',$ids['mona'],'booked','حجز وحدة بمشروع النخيل',dBack(9),dBack(2),null]); $il->execute(['طارق حسن','01012345679',$ids['mahmoud'],'new','',dBack(1),null,null]); $il->execute(['سلمى ناصر','01012345680',$ids['sara'],'follow','تحتاج عرض سعر نهائي',dBack(3),dBack(0),dBack(0)]); $il->execute(['حسام الدين','01012345681',$ids['ahmed'],'new','',dBack(0),null,null]); $il->execute(['مي كامل','01012345682',$ids['mona'],'new','',dBack(0),null,null]); settingSet($pdo,'sysName','سعىي سبحثشن'); settingSet($pdo,'dist','rr'); settingSet($pdo,'agentEdit',true); settingSet($pdo,'rrIdx',0); settingSet($pdo,'v',1); addLog($pdo,'النظام','تهيئة النظام وإنشاء الحسابات الافتراضية'); } /* لو نُفذ SQL يدوي سابقاً بتجزئات مؤقتة — يُصلح تلقائياً */ foreach($pdo->query("SELECT id,username FROM users WHERE pass_hash='placeholder'") as $u){ $pw=($u['username']==='admin')?'admin123':'123456'; $pdo->prepare('UPDATE users SET pass_hash=? WHERE id=?')->execute([password_hash($pw,PASSWORD_DEFAULT),$u['id']]); } } ensureSeed($pdo); /* ---------- [6] المصادقة والأدوار ---------- */ function tokenOf(){ $h=$_SERVER['HTTP_AUTHORIZATION']??($_SERVER['REDIRECT_HTTP_AUTHORIZATION']??''); if(!$h && function_exists('apache_request_headers')){ foreach(apache_request_headers() as $k=>$v){ if(strtolower($k)==='authorization'){ $h=$v; break; } } } if($h && stripos($h,'bearer ')===0) $h=trim(substr($h,7)); if(!$h && isset($_GET['token'])) $h=$_GET['token']; return trim((string)$h); } function authUser($pdo){ $t=tokenOf(); if($t==='') return null; $s=$pdo->prepare('SELECT t.expires,u.* FROM tokens t JOIN users u ON u.id=t.user_id WHERE t.token=?'); $s->execute([$t]); $r=$s->fetch(); if(!$r || (int)$r['expires']'انتهت الجلسة — سجل الدخول من جديد'],JF); exit; } return $u; } function requireAdmin($u){ if($u['role']!=='admin'){ http_response_code(403); echo json_encode(['error'=>'هذه العملية من صلاحيات المدير فقط'],JF); exit; } } function body(){ $d=json_decode(file_get_contents('php://input'),true); return is_array($d)?$d:[]; } function fail($code,$msg){ http_response_code($code); echo json_encode(['error'=>$msg],JF); exit; } function agentsList($pdo){ return $pdo->query("SELECT u.id,u.username,u.name,u.job,u.phone,u.active,u.role, (SELECT COUNT(*) FROM leads l WHERE l.agent_id=u.id) AS total, (SELECT COUNT(*) FROM leads l WHERE l.agent_id=u.id AND l.status='booked') AS booked FROM users u WHERE u.role='employee' ORDER BY u.id")->fetchAll(); } function actives($pdo){ return $pdo->query("SELECT id FROM users WHERE role='employee' AND active=1 ORDER BY id")->fetchAll(); } function loadOf($pdo,$id){ return (int)$pdo->prepare('SELECT COUNT(*) c FROM leads WHERE agent_id=?') ? 0 : 0; } /* ---------- [7] التوجيه ---------- */ $action=$_GET['action']??''; switch($action){ /* ============ تسجيل الدخول ============ */ case 'login': { $b=body(); $un=strtolower(trim($b['username']??'')); $s=$pdo->prepare('SELECT * FROM users WHERE username=?'); $s->execute([$un]); $u=$s->fetch(); if(!$u||!(int)$u['active']||!password_verify($b['password']??'',$u['pass_hash'])) fail(401,'اسم المستخدم أو كلمة المرور غير صحيحة'); $token=bin2hex(random_bytes(32)); $pdo->prepare('INSERT INTO tokens(token,user_id,expires) VALUES(?,?,?)') ->execute([$token,$u['id'],(time()+TOKEN_DAYS*86400)*1000]); $pdo->prepare('DELETE FROM tokens WHERE expiresexecute([time()*1000]); echo json_encode(['token'=>$token,'user'=>['id'=>(int)$u['id'],'name'=>$u['name'],'role'=>$u['role'],'job'=>$u['job'],'username'=>$u['username']]],JF); exit; } /* ============ تحميل البيانات (حسب الدور) ============ */ case 'bootstrap': { $me=requireAuth($pdo); if($me['role']==='admin') $leads=$pdo->query('SELECT * FROM leads ORDER BY id DESC')->fetchAll(); else { $s=$pdo->prepare('SELECT * FROM leads WHERE agent_id=? ORDER BY id DESC'); $s->execute([$me['id']]); $leads=$s->fetchAll(); } echo json_encode([ 'user'=>['id'=>(int)$me['id'],'name'=>$me['name'],'role'=>$me['role'],'job'=>$me['job'],'username'=>$me['username']], 'sysName'=>settingGet($pdo,'sysName','سعىي سبحثشن'), 'dist'=>settingGet($pdo,'dist','rr'), 'agentEdit'=>(bool)settingGet($pdo,'agentEdit',true), 'agents'=>agentsList($pdo), 'leads'=>$leads, 'log'=>$me['role']==='admin'?$pdo->query('SELECT * FROM activity_log ORDER BY id DESC LIMIT 30')->fetchAll():[], 'v'=>(int)settingGet($pdo,'v',0), ],JF); exit; } /* ============ عداد الإصدار (للمزامنة الدورية) ============ */ case 'version': { requireAuth($pdo); if(random_int(1,20)===1) $pdo->prepare('DELETE FROM tokens WHERE expiresexecute([time()*1000]); echo json_encode(['v'=>(int)settingGet($pdo,'v',0)]); exit; } /* ============ إضافة عميل ============ */ case 'leads': { $me=requireAuth($pdo); $b=body(); $phone=preg_replace('/\D/','',$b['phone']??''); if(strlen($phone)<8) fail(400,'رقم هاتف غير صحيح'); $s=$pdo->prepare('SELECT id FROM leads WHERE phone=?'); $s->execute([$phone]); if($s->fetch()) fail(409,'هذا الرقم مسجل بالفعل'); if($me['role']==='admin'){ $aid=($b['agent_id']??'')==='auto'?'assign':(int)($b['agent_id']??0); } else $aid=(int)$me['id']; $st=in_array($b['st']??'',['new','follow','booked','off'],true)?$b['st']:'new'; $name=trim($b['name']??'')?:'عميل جديد'; if($aid==='assign'){ $act=actives($pdo); if(!count($act)) fail(400,'لا يوجد موظفون نشطون للتوزيع'); $idx=(int)settingGet($pdo,'rrIdx',0); settingSet($pdo,'rrIdx',$idx+1); $aid=(int)$act[$idx%count($act)]['id']; } elseif($aid<=0) $aid=null; $lc=($st!=='new')?todayS():null; $due=($st==='follow')?($b['due_date']??''):null; $pdo->prepare('INSERT INTO leads(name,phone,agent_id,status,note,added_on,last_contact,due_date) VALUES(?,?,?,?,?,?,?,?)') ->execute([$name,$phone,$aid,$st,trim($b['note']??''),todayS(),$lc?:null,$due?:null]); addLog($pdo,$me['name'],'أضاف العميل '.$name); bump($pdo); echo json_encode(['ok'=>true],JF); exit; } /* ============ إدخال جماعي + توزيع تلقائي ============ */ case 'leads_bulk': { $me=requireAuth($pdo); requireAdmin($me); $b=body(); $text=(string)($b['text']??''); $strategy=($b['strategy']??'rr')==='ll'?'ll':'rr'; $auto=!isset($b['autoAssign'])||(bool)$b['autoAssign']; $seen=[]; foreach($pdo->query('SELECT phone FROM leads') as $r) $seen[$r['phone']]=true; $rows=[]; $dup=0; foreach(preg_split('/\n+/',$text) as $line){ $line=trim($line); if($line==='') continue; if(preg_match('/(\+?\d[\d\s\-]{5,})/',$line,$m)){ $phone=preg_replace('/\D/','',$m[1]); $name=trim(preg_replace('/[,\-–—:|.]+/u',' ',str_replace($m[1],'',$line))); } else { $phone=''; $name=trim($line); } if(strlen($phone)>11 && substr($phone,0,2)==='20') $phone='0'.substr($phone,2); if(strlen($phone)>11) $phone=substr($phone,-11); if(strlen($phone)<8){ $dup++; continue; } if(isset($seen[$phone])){ $dup++; continue; } $seen[$phone]=true; $rows[]=['name'=>$name!==''?$name:'عميل جديد','phone'=>$phone]; } if(!count($rows)) fail(400,'لا توجد سطور صالحة'); $act=actives($pdo); if(!count($act)) fail(400,'لا يوجد موظفون نشطون للتوزيع'); $counts=[]; foreach($act as $a) $counts[$a['id']]=(int)$pdo->query('SELECT COUNT(*) c FROM leads WHERE agent_id='.(int)$a['id'])->fetch()['c']; $per=[]; $i=0; $pdo->beginTransaction(); $ins=$pdo->prepare('INSERT INTO leads(name,phone,agent_id,status,note,added_on) VALUES(?,?,?,"new","",?)'); foreach($rows as $r){ $id=null; if($auto){ if($strategy==='ll'){ $min=array_keys($counts,min($counts))[0]; $id=(int)$min; $counts[$min]++; } else { $id=(int)$act[$i%count($act)]['id']; $i++; } } $ins->execute([$r['name'],$r['phone'],$id,todayS()]); if($id) $per[$id]=($per[$id]??0)+1; } $pdo->commit(); addLog($pdo,$me['name'],'أدخل '.count($rows).' عميلاً جماعياً'.($auto?' ووزعهم':'')); bump($pdo); echo json_encode(['ok'=>true,'added'=>count($rows),'dup'=>$dup,'per'=>$per],JF); exit; } /* ============ تعديل سجل ============ */ case 'lead_update': { $me=requireAuth($pdo); $b=body(); $id=(int)($b['id']??0); $s=$pdo->prepare('SELECT * FROM leads WHERE id=?'); $s->execute([$id]); $l=$s->fetch(); if(!$l) fail(404,'السجل غير موجود'); $isAdmin=($me['role']==='admin'); if(!$isAdmin && (int)$l['agent_id']!==(int)$me['id']) fail(403,'هذا السجل ليس من سجلاتك'); if(!$isAdmin && !settingGet($pdo,'agentEdit',true)) fail(403,'التعديل معطّل حالياً من الإدارة'); $sets=[]; $vals=[]; if($isAdmin){ if(isset($b['name']) && trim($b['name'])!==''){ $sets[]='name=?'; $vals[]=trim($b['name']); } if(isset($b['phone'])){ $p=preg_replace('/\D/','',$b['phone']); if(strlen($p)>=8){ $sets[]='phone=?'; $vals[]=$p; } } if(array_key_exists('agent_id',$b)){ $sets[]='agent_id=?'; $vals[]=((int)$b['agent_id'])?:null; } } if(isset($b['status']) && in_array($b['status'],['new','follow','booked','off'],true)){ if($l['status']==='new' && $b['status']!=='new' && empty($l['last_contact'])){ $sets[]='last_contact=?'; $vals[]=todayS(); } $sets[]='status=?'; $vals[]=$b['status']; } if(isset($b['note'])){ $sets[]='note=?'; $vals[]=trim($b['note']); } if(isset($b['due_date'])){ $sets[]='due_date=?'; $vals[]=$b['due_date']?:null; } if(isset($b['last_contact'])){ $sets[]='last_contact=?'; $vals[]=$b['last_contact']?:null; } if(count($sets)){ $vals[]=$id; $pdo->prepare('UPDATE leads SET '.implode(',',$sets).' WHERE id=?')->execute($vals); addLog($pdo,$me['name'],'عدّل السجل #'.$id); bump($pdo); } echo json_encode(['ok'=>true],JF); exit; } /* ============ حذف سجل ============ */ case 'lead_delete': { $me=requireAuth($pdo); requireAdmin($me); $id=(int)(body()['id']??0); $s=$pdo->prepare('SELECT name FROM leads WHERE id=?'); $s->execute([$id]); $l=$s->fetch(); if(!$l) fail(404,'غير موجود'); $pdo->prepare('DELETE FROM leads WHERE id=?')->execute([$id]); addLog($pdo,$me['name'],'حذف السجل «'.$l['name'].'»'); bump($pdo); echo json_encode(['ok'=>true],JF); exit; } /* ============ توزيع الداتا المنتظرة ============ */ case 'distribute': { $me=requireAuth($pdo); requireAdmin($me); $pool=$pdo->query('SELECT id FROM leads WHERE agent_id IS NULL')->fetchAll(); if(!count($pool)) fail(400,'لا توجد داتا في الانتظار'); $act=actives($pdo); if(!count($act)) fail(400,'لا يوجد موظفون نشطون'); $strategy=settingGet($pdo,'dist','rr'); $counts=[]; foreach($act as $a) $counts[$a['id']]=(int)$pdo->query('SELECT COUNT(*) c FROM leads WHERE agent_id='.(int)$a['id'])->fetch()['c']; $per=[]; $i=(int)settingGet($pdo,'rrIdx',0); $pdo->beginTransaction(); $up=$pdo->prepare('UPDATE leads SET agent_id=? WHERE id=?'); foreach($pool as $p){ if($strategy==='ll'){ $min=array_keys($counts,min($counts))[0]; $id=(int)$min; $counts[$min]++; } else { $id=(int)$act[$i%count($act)]['id']; $i++; } $up->execute([$id,$p['id']]); $per[$id]=($per[$id]??0)+1; } settingSet($pdo,'rrIdx',$i); $pdo->commit(); addLog($pdo,$me['name'],'وزّع '.count($pool).' عميلاً من الانتظار'); bump($pdo); echo json_encode(['ok'=>true,'distributed'=>count($pool),'per'=>$per],JF); exit; } /* ============ إضافة موظف ============ */ case 'agents_add': { $me=requireAuth($pdo); requireAdmin($me); $b=body(); $un=strtolower(trim($b['username']??'')); if(!preg_match('/^[a-z0-9_.]{3,20}$/',$un)) fail(400,'اسم الدخول: حروف إنجليزية/أرقام من 3 إلى 20'); $s=$pdo->prepare('SELECT id FROM users WHERE username=?'); $s->execute([$un]); if($s->fetch()) fail(409,'اسم الدخول مستخدم بالفعل'); $pdo->prepare('INSERT INTO users(username,pass_hash,salt,name,role,job,phone,active) VALUES(?,?,?,?,?,?,?,1)') ->execute([$un,password_hash($b['password']?:'123456',PASSWORD_DEFAULT),'',trim($b['name']??'')?:$un,'employee',trim($b['job']??'')?:'مبيعات',trim($b['phone']??'')]); addLog($pdo,$me['name'],'أضاف الموظف '.trim($b['name']??$un)); bump($pdo); echo json_encode(['ok'=>true],JF); exit; } /* ============ تعديل موظف ============ */ case 'agent_update': { $me=requireAuth($pdo); requireAdmin($me); $b=body(); $id=(int)($b['id']??0); $s=$pdo->prepare('SELECT * FROM users WHERE id=? AND role="employee"'); $s->execute([$id]); $u=$s->fetch(); if(!$u) fail(404,'الموظف غير موجود'); if(isset($b['name']) && trim($b['name'])!=='') $pdo->prepare('UPDATE users SET name=? WHERE id=?')->execute([trim($b['name']),$id]); if(isset($b['job'])) $pdo->prepare('UPDATE users SET job=? WHERE id=?')->execute([trim($b['job']),$id]); if(isset($b['phone'])) $pdo->prepare('UPDATE users SET phone=? WHERE id=?')->execute([trim($b['phone']),$id]); if(isset($b['active']))$pdo->prepare('UPDATE users SET active=? WHERE id=?')->execute([$b['active']?1:0,$id]); if(!empty($b['password'])) $pdo->prepare('UPDATE users SET pass_hash=? WHERE id=?')->execute([password_hash($b['password'],PASSWORD_DEFAULT),$id]); addLog($pdo,$me['name'],'عدّل بيانات الموظف '.$u['name']); bump($pdo); echo json_encode(['ok'=>true],JF); exit; } /* ============ إعدادات النظام ============ */ case 'settings': { $me=requireAuth($pdo); requireAdmin($me); $b=body(); if(isset($b['sysName']) && trim($b['sysName'])!=='') settingSet($pdo,'sysName',trim($b['sysName'])); if(isset($b['dist'])) settingSet($pdo,'dist',$b['dist']==='ll'?'ll':'rr'); if(isset($b['agentEdit'])) settingSet($pdo,'agentEdit',(bool)$b['agentEdit']); addLog($pdo,$me['name'],'عدّل إعدادات النظام'); bump($pdo); echo json_encode(['ok'=>true],JF); exit; } /* ============ نسخة احتياطية ============ */ case 'backup': { $me=authUser($pdo); requireAdmin($me); addLog($pdo,$me['name'],'أنشأ نسخة احتياطية'); header('Content-Disposition: attachment; filename="saii-backup-'.todayS().'.json"'); echo json_encode([ 'exported_at'=>round(microtime(true)*1000), 'users'=>$pdo->query('SELECT * FROM users')->fetchAll(), 'leads'=>$pdo->query('SELECT * FROM leads')->fetchAll(), 'settings'=>$pdo->query('SELECT * FROM settings')->fetchAll(), 'log'=>$pdo->query('SELECT * FROM activity_log')->fetchAll(), ],JF); exit; } /* ============ استرجاع نسخة ============ */ case 'restore': { $me=requireAuth($pdo); requireAdmin($me); $d=body(); if(!isset($d['users'])||!isset($d['leads'])) fail(400,'ملف النسخة غير صالح'); $pdo->beginTransaction(); $pdo->exec('DELETE FROM leads'); $pdo->exec('DELETE FROM tokens'); $pdo->exec('DELETE FROM users'); $pdo->exec('DELETE FROM settings'); $pdo->exec('DELETE FROM activity_log'); $iu=$pdo->prepare('INSERT INTO users(id,username,pass_hash,salt,name,role,job,phone,active) VALUES(?,?,?,?,?,?,?,?,?)'); foreach($d['users'] as $u) $iu->execute([$u['id'],$u['username'],$u['pass_hash'],$u['salt']??'',$u['name'],$u['role'],$u['job']??'مبيعات',$u['phone']??'',!empty($u['active'])?1:0]); /* ضمان بقاء المدير الحالي قادراً على الدخول */ $chk=$pdo->prepare('SELECT id FROM users WHERE username=?'); $chk->execute([$me['username']]); if(!$chk->fetch()) $iu->execute([$me['id'],$me['username'],$me['pass_hash'],$me['salt'],$me['name'],'admin',$me['job'],$me['phone'],1]); $il=$pdo->prepare('INSERT INTO leads(id,name,phone,agent_id,status,note,added_on,last_contact,due_date) VALUES(?,?,?,?,?,?,?,?,?)'); foreach($d['leads'] as $l) $il->execute([$l['id'],$l['name'],$l['phone'],$l['agent_id']?:null,$l['status'],$l['note']??'',$l['added_on'],$l['last_contact']??null,$l['due_date']??null]); $is=$pdo->prepare('INSERT INTO settings(skey,svalue) VALUES(?,?)'); foreach(($d['settings']??[]) as $s) $is->execute([$s['skey'],$s['svalue']]); $ig=$pdo->prepare('INSERT INTO activity_log(at,actor,action) VALUES(?,?,?)'); foreach(($d['log']??[]) as $g) $ig->execute([$g['at'],$g['actor']??'',$g['action']]); foreach(['users','leads'] as $t){ $m=(int)$pdo->query('SELECT COALESCE(MAX(id),1) m FROM '.$t)->fetch()['m']; $pdo->exec('ALTER TABLE '.$t.' AUTO_INCREMENT='.($m+1)); } $pdo->commit(); addLog($pdo,$me['name'],'استرجع نسخة احتياطية ('.count($d['leads']).' سجل)'); bump($pdo); echo json_encode(['ok'=>true,'leads'=>count($d['leads'])],JF); exit; } default: fail(404,'الإجراء غير معروف'); }