<?php
/*
 本代码由 焕岱科技 创建
 技术支持 WX：15285007200
 严禁反编译、逆向等任何形式的侵权行为，违者将追究法律责任
*/

// 公共助手函数

use think\exception\HttpResponseException;
use think\Response;
use think\Cache;
use think\Db;

/**
 * 判断索引是否存在
 * @param string $table 表名
 * @param string $indexName 索引名称
 * @return bool
 */
function hasIndex($table,$indexName)
{
    $table = tablename($table);
    $res = Db::query("SHOW INDEX FROM {$table} WHERE Key_name = '{$indexName}'");
    return !empty($res);
}

/**
 * 移除URL中的协议+域名，只保留路径
 * @param string $url
 * @return string
 */
function stripUrlDomain(string $url): string
{
    if (trim($url) === '') {
        return '';
    }
    // 匹配：http://  https://  //域名 这类头部
    $reg = '/^(https?:\/\/)?([^\/]+)/i';
    $path = preg_replace($reg, '', $url);
    return $path;
}

function printData($data){
    if(is_array($data)){
        echo "<pre>";
    }
    print_r($data);die;
}

function addFileLog($filename,$log,$append=false){
    if(!is_string($log)){
        $log = toJsonen($log);
    }
    if (!file_exists(RUNTIME_PATH."/bbfx")) {
        mkdir(RUNTIME_PATH."/bbfx", 0777, true);
    }
    if($append){
        file_put_contents(RUNTIME_PATH."/bbfx/".$filename.".txt",$log."\r\n",FILE_APPEND);
    }
    else{
        file_put_contents(RUNTIME_PATH."/bbfx/".$filename.".txt",$log);
    }
}

function bd_number($num)
{
    $val = bcsub($num, '0', 2);
    // 格式化保证一定两位小数
    return sprintf('%.2f', $val);
}

function rgbToHex($rgb) {

    if(strstr($rgb,"#")){
        return $rgb;
    }

    $rgb = str_replace("rgba(","",$rgb);
    $rgb = str_replace("rgb(","",$rgb);
    $rgb = str_replace(")","",$rgb);
    $rgb = explode(",",$rgb);
    
    foreach($rgb as &$v){
        $v = intval($v);
    }
    unset($v);

    $r = $rgb[0];
    $g = $rgb[1]; 
    $b = $rgb[2];

    // 确保值在0到255之间
    $r = max(0, min(255, $r));
    $g = max(0, min(255, $g));
    $b = max(0, min(255, $b));

    // 将每个通道的值转换为十六进制，并确保是两位数
    $hexR = str_pad(dechex($r), 2, '0', STR_PAD_LEFT);
    $hexG = str_pad(dechex($g), 2, '0', STR_PAD_LEFT);
    $hexB = str_pad(dechex($b), 2, '0', STR_PAD_LEFT);

    // 拼接成最终的16进制颜色代码
    return "#$hexR$hexG$hexB";
}

function bbfx_finish_request(){
    if(function_exists("fastcgi_finish_request")){
        ob_flush();
        flush();
        fastcgi_finish_request();
    }
}

function download_file($url, $path,$filename){
    if (!file_exists($path)) {
        mkdir($path, 0777, true);
    }
    
    session_write_close();
        
    $file_path = $path.$filename;

    // 初始化 curl 会话
    $ch = curl_init();
    
    // 设置要请求的 URL
    curl_setopt($ch, CURLOPT_URL, $url);
    // 设置请求超时时间（单位：秒）
    curl_setopt($ch, CURLOPT_TIMEOUT, 3600);
    // 设置输出文件流
    curl_setopt($ch, CURLOPT_FILE, fopen($file_path, 'w+'));
    // 开启重定向跟踪功能
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    // 执行 curl 请求
    $result = curl_exec($ch);
    // 获取 HTTP 状态码
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    // 关闭 curl 会话
    curl_close($ch);
    // 如果请求失败或HTTP状态码不是200，删除该文件并返回false
    if ($result === false || $httpcode !== 200) {
        unlink($file_path);
        return false;
    }
    // 返回true表示下载成功
    return $file_path;
}
function deleteDir($dirPath) {
    if (!is_dir($dirPath)) {
        throw new InvalidArgumentException("$dirPath must be a directory");
        return false;
    }
    if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
        $dirPath .= '/';
    }
    $files = scandir($dirPath);
    foreach ($files as $file) {
        if ($file != '.' && $file != '..') {
            $filePath = $dirPath . $file;
            if (is_dir($filePath)) {
                deleteDir($filePath);
            } else {
                unlink($filePath);
            }
        }
    }
    return rmdir($dirPath);
}
function copyDirectory($source, $dest) {
    // 检查源目录是否存在
    if (is_dir($source)) {
        if (!is_dir($dest)) {
            // 创建目标目录
            mkdir($dest, 0755, true);
        }
        
        // 打开源目录
        $dir = opendir($source);
        while (($file = readdir($dir)) !== false) {
            if (($file != '.') && ($file != '..')) {
                if (is_dir($source . '/' . $file)) {
                    // 递归复制子目录
                    copyDirectory($source . '/' . $file, $dest . '/' . $file);
                } else {
                    // 复制文件
                    copy($source . '/' . $file, $dest . '/' . $file);
                }
            }
        }
        closedir($dir);
    } else {
        // echo "Source directory does not exist.";
    }
}

function zipDirectory($source, $destination,$filename='') {
    if (!extension_loaded('zip') || !file_exists($source)) {
        return __json(0,"操作失败");
    }
    
    unlink($destination);
    
    // 创建 ZIP 文件
    $zip = new \ZipArchive();
    if (!$zip->open($destination, \ZipArchive::CREATE)) {
        return __json(0,"创建zip文件失败");
    }
    
    // 递归添加文件夹中的所有文件和子文件夹
    $source = realpath($source);
    // print_r($source);die;
    if (is_dir($source) === true) {
        $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source), \RecursiveIteratorIterator::SELF_FIRST);
        // echo "<pre>";
        // print_r($files);die;
        $filename1 = $filename;
        if($filename){
            $filename1 = $filename."\\";
            $filename = $filename."/";
        }
        // print_r($files);die;
        $list = [];
        foreach ($files as $file) {
            
            $file = realpath($file);
            if(!strstr($file, '/'.$filename) && !strstr($file, "\\".$filename1)){
                continue;
            }
            
            $is_windows = false;
            if(strstr($file, "\\".$filename1)){
                $is_windows = true;
            }
            
            $list[] = $file;
            
            if (is_dir($file) === true) {
                if($is_windows){
                    $filepath = $filename.str_replace($source . '\\', '', $file . '\\');
                }
                else{
                    $filepath = $filename.str_replace($source . '/', '', $file . '/');
                }
                $res = $zip->addEmptyDir($filepath);
            } else if (is_file($file) === true) {
                
                if($is_windows){
                    $filepath = $filename.str_replace($source . '\\', '', $file);
                }
                else{
                    $filepath = $filename.str_replace($source . '/', '', $file);
                }
                $res = $zip->addFile($file, $filepath);
                // print_r($file);die;
            }
        }
        // print_r($list);die;
    } else if (is_file($source) === true) {
        $zip->addFile($source, basename($source));
    }
    $zip->close();
    
    // echo "<pre>";
    // print_r($list);die;
    
    // 关闭 ZIP 文件
    return __json(1,"操作成功");
}
function freezeUserTips($user){
    if(!empty($user) && $user['status'] != 1){
        __error("您的账号已被冻结，请联系管理员");
    }
    return false;
}
function cdnurls($urls,$field=''){
    if(empty($urls)){
        return [];
    }
    
    if(!is_array($urls)){
        if(is_string($urls)){
            $urls = explode(",",$urls);
        }
        else{
            return [];
        }
    }
    
    $list = [];
    foreach ($urls as $key => $val){
        if(!empty($field)){
            $val[$field] = cdnurl($val[$field]);
            $list[] = $val;
        }
        else{
            if(!empty($val)){
                $val = cdnurl($val);
                $list[] = $val;
            }
        }
    }
    
    return $list;
}
function getdistance($lng1,$lat1,$lng2,$lat2){
    //将角度转为狐度 
    $radLat1=deg2rad($lat1);
    $radLat2=deg2rad($lat2);
    $radLng1=deg2rad($lng1);
    $radLng2=deg2rad($lng2);
    $a=$radLat1-$radLat2;//两纬度之差,纬度<90
    $b=$radLng1-$radLng2;//两经度之差纬度<180
    $s=2*asin(sqrt(pow(sin($a/2),2)+cos($radLat1)*cos($radLat2)*pow(sin($b/2),2)))*6378.137;
    return round($s,2);
}

function timeConvert($time){
    $stime = time() - $time;
    $timeText = "";
    if($stime > 60){
        $year = intval($stime / (365*24*60*60));
        if($year > 0){
            $timeText = "{$year}年前";
        }
        else{
            $month = intval($stime / (30*24*60*60));
            if($month > 0){
                $timeText = "{$month}个月前";
            }
            else{
                $day = intval($stime / (24*60*60));
                if($day > 0){
                    $timeText = "{$day}天前";
                }
                else{
                    $hour = intval($stime / (60*60));
                    if($hour > 0){
                        $timeText = "{$hour}个小时前";
                    }
                    else{
                        $minute = intval($stime / 60);
                        $timeText = "{$minute}分钟前";
                    }
                }
            }
        }
    }
    else{
        $timeText = "刚刚";
    }
    
    return $timeText;
}

function saveFile($url,$savePath){
   
    
    $curl = curl_init($url);
    $fileHandler = fopen($savePath, 'w');
    
    curl_setopt($curl, CURLOPT_FILE, $fileHandler);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    
    curl_exec($curl);
    
    $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    
    curl_close($curl);
    fclose($fileHandler);
    
    if ($statusCode == 200) {
        return true;
    } else {
        return false;
    }
}

function resizeImage($file, $width, $height=0) {
    list($origWidth, $origHeight) = getimagesize($file);
    
    if($height == 0){
        $ratio = $origWidth / $origHeight;
        if ($width / $height > $ratio) {
            $width = $height * $ratio;
        } 
        else {
            $height = $width / $ratio;
        }
    }
    $parts = explode('.', $file);
    $extension = end($parts);
    
    if($extension == 'png'){
        $src = imagecreatefrompng($file);
    }
    else if($extension == 'gif'){
        $src = imagecreatefromgif($file);
    }
    else{
        $src = imagecreatefromjpeg($file);
    }
    
    
    $dst = imagecreatetruecolor($width, $height);
    $res = imagecopyresampled($dst, $src, 0, 0, 0, 0, $width, $height, $origWidth, $origHeight);
    
 
    $filename = basename($file);
    $filepath = str_replace($filename,"",$file)."thumb_".$filename;
    
    
    imagejpeg($dst, $filepath);
 
    imagedestroy($src);
    imagedestroy($dst);
    
    return $filepath;
}
 


function filterData($list,$fields=[]){
    
    if(!is_array($list) || empty($fields) || empty($list)){
        return $list;
    }
    
    if(!is_array($fields)){
        if(is_string($fields)){
            $fields = explode(",",$fields);
        }
        else{
            return $list;
        }
    }
    
    foreach ($fields as $key => $val){
        if(array_key_exists($val, $list)){
            unset($list[$val]);
        }
    }
    
    return $list;
}

function showTableIndex($table,$Key_name){

    $data = db()->query("SHOW INDEX FROM ".tablename($table)." WHERE Key_name = '".$Key_name."';");
    
    return $data;
}

function pdo_tableexists($table){
    $isTable=db()->query("SHOW TABLES LIKE '%".$table."'");
    
    if(!empty($isTable)){
        return true;
    }
    else{
        return false;
    }
}
function tablename($table){
    $prefix = config("database.prefix");
    return "`{$prefix}{$table}`";
}
function array_skey($array,$xkey){
    $list = [];
    
    if(!empty($array) && is_array($array) && !empty($array[0]) && !empty($array[0][$xkey])){
        
        foreach ($array as $key => $val){
            $list[$val[$xkey]] = $val;
        }
    }
    
    return $list;
}

function toFixed($number){
    $number = (string)$number;
    return floor($number * '100') / '100';
}
function _number($number,$type=2){
    if(!is_numeric($number)){
        $number = round($number,2);
    }
    if($type == 1){
        $number = toFixed($number);
    }
    else if($type == 3){
        $number = (string)$number;
        $number = ceil($number * '100') / '100';
    }
    else{
        $number = round($number,2);
    }
    
    return round($number,2);
}

function tomediaPage($url){
    global $_W;
    
    if(empty($url)){
        return "";
    }
    
    $url = cdnurl($url);
    
    return $url;
}

function replaceSiteroot($url,$siteroot=""){
    global $_W;
    
    if(empty($url)){
        return "";
    }
    
    if(empty($siteroot)){
        $siteroot = request()->domain();
    }
    
    $url = str_replace($siteroot,"",$url);
    
    return $url;
}

function replaceSiteroots($urls,$field=""){
    if(empty($urls)){
        return [];
    }
    
    if(!is_array($urls)){
        if(is_string($urls)){
            $urls = explode(",",$urls);
        }
        else{
            return [];
        }
    }
    
    $list = [];
    foreach ($urls as $key => $val){
        if(!empty($val)){
            if(is_array($val)){
                if(!empty($val[$field])){
                    $val[$field] = replaceSiteroot($val[$field]);
                }
            }
            else{
                $val = replaceSiteroot($val);
            }

            $list[] = $val;
        }
    }
    
    return $list;
}

function secret($str, $is_pwd = true, $start = 1, $end = 1){
	$strlen = mb_strlen($str, 'utf-8');

	if ($strlen < 2) {
		if (empty($str)) {
			return '';
		}
		return ($is_pwd ? '********' : $str);
	}


	$firstStr = mb_substr($str, 0, $start, 'utf-8');
	$lastStr = mb_substr($str, -1 * $end, $end, 'utf-8');
	return ($strlen == 2 ? $firstStr . str_repeat('*', $strlen - 1) : $firstStr . str_repeat('*', $strlen - $start - $end) . $lastStr);
}

function enid($id){
    if(is_array($id) && !empty($id)){
        $new_id = [];
        foreach ($id as $key => $val){
            if(!empty($val) && $key >= 0){
                $new_id[] = $val;
            }
        }
        if(empty($new_id)){
            return "";
        }
        return ",".implode(",",$new_id).",";
    }
    else{
        return "";
    }
}
function deid($id,$nmu=false){
    if(empty($id)){
        return [];
    }
    if(is_string($id) || is_numeric($id)){
        $id = explode(",",$id);
        $new_id = [];
        foreach ($id as $key => $val){
            if($val != ''){
                if($nmu) $val = intval($val);
                $new_id[] = $val;
            }
        }
        return $new_id;
    }
    else{
        return [];
    }
}

function iserializer($value) {
	return serialize($value);
}


function iunserializer($value) {
	if (empty($value)) {
		return array();
	}
	if (!is_serialized($value)) {
		return $value;
	}
	if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
		$result = unserialize($value, array('allowed_classes' => false));
	} else {
		if (preg_match('/[oc]:[^:]*\d+:/i', $value)) {
			return array();
		}
		$result = unserialize($value);
	}
	if (false === $result) {
		$temp = preg_replace_callback('!s:(\d+):"(.*?)";!s', function ($matchs) {
			return 's:' . strlen($matchs[2]) . ':"' . $matchs[2] . '";';
		}, $value);

		return unserialize($temp);
	} else {
		return $result;
	}
}

function is_serialized($data, $strict = true) {
	if (!is_string($data)) {
		return false;
	}
	$data = trim($data);
	if ('N;' == $data) {
		return true;
	}
	if (strlen($data) < 4) {
		return false;
	}
	if (':' !== $data[1]) {
		return false;
	}
	if ($strict) {
		$lastc = substr($data, -1);
		if (';' !== $lastc && '}' !== $lastc) {
			return false;
		}
	} else {
		$semicolon = strpos($data, ';');
		$brace = strpos($data, '}');
				if (false === $semicolon && false === $brace) {
			return false;
		}
				if (false !== $semicolon && $semicolon < 3) {
			return false;
		}
		if (false !== $brace && $brace < 4) {
			return false;
		}
	}
	$token = $data[0];
	switch ($token) {
		case 's':
			if ($strict) {
				if ('"' !== substr($data, -2, 1)) {
					return false;
				}
			} elseif (false === strpos($data, '"')) {
				return false;
			}
						case 'a':
			return (bool) preg_match("/^{$token}:[0-9]+:/s", $data);
		case 'O':
			return false;
		case 'b':
		case 'i':
		case 'd':
			$end = $strict ? '$' : '';

			return (bool) preg_match("/^{$token}:[0-9.E-]+;$end/", $data);
	}

	return false;
}

function __error($code=0,$msg="",$data=[]){
    if(is_string($code)){
        if(!empty($msg)){
            $data = $msg;
        }
        $msg = $code;
        $code = 0;
    }
    $result = ['code'=>$code,'message'=>$msg,'data'=>$data];
    exit(toJsonen($result));die; 
}
function __success($msg="",$data=[]){
    $result = ['code'=>1,'message'=>$msg,'data'=>$data];
    exit(toJsonen($result));die; 
}
function __json($code,$msg="",$data=[]){
    $result = ['code'=>$code,'message'=>$msg,'data'=>$data];
    return $result; 
}
function __result($result){
    exit(toJsonen($result));die; 
}
function toJsonen($data){
    return json_encode($data,JSON_UNESCAPED_UNICODE);
}
function toJsonde($data){
    return json_decode($data,true);
}

/*
**遍历删除文件夹
**@param $dir 要删除文件夹的文件夹 
*/
function del_Dir($dir){
    $flag = is_empty_dir($dir);
    if( $flag==false ){
        $dp = opendir($dir);
        while(false !== $file = readdir($dp)){
            if($file != "." && $file != ".." ){
                if( is_dir("$dir/$file") ){
                    del_Dir("$dir/$file");
                }else{
                    unlink("$dir/$file");
                }
            }    
        }
        closedir($dp);
        rmdir($dir);
    }else{
        rmdir($dir);
    }
}
/*
**判断文件夹是否为空
**@param 要判断的文件夹
*/
function is_empty_dir($dir){
    $flag = true;
    if( is_dir($dir) ){
        $dp = opendir($dir);
        while(false !== $file = readdir($dp)){
            if($file != "." && $file != ".."){
                $flag = false;
            }
        }
        return $flag;
    }else{
        return true;
    }
}

if (!function_exists('__')) {

    /**
     * 获取语言变量值
     * @param string $name 语言变量名
     * @param array  $vars 动态变量值
     * @param string $lang 语言
     * @return mixed
     */
    function __($name, $vars = [], $lang = '')
    {
        if (is_numeric($name) || !$name) {
            return $name;
        }
        if (!is_array($vars)) {
            $vars = func_get_args();
            array_shift($vars);
            $lang = '';
        }
        return \think\Lang::get($name, $vars, $lang);
    }
}

if (!function_exists('format_bytes')) {

    /**
     * 将字节转换为可读文本
     * @param int    $size      大小
     * @param string $delimiter 分隔符
     * @param int    $precision 小数位数
     * @return string
     */
    function format_bytes($size, $delimiter = '', $precision = 2)
    {
        $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
        for ($i = 0; $size >= 1024 && $i < 6; $i++) {
            $size /= 1024;
        }
        return round($size, $precision) . $delimiter . $units[$i];
    }
}

if (!function_exists('datetime')) {

    /**
     * 将时间戳转换为日期时间
     * @param int    $time   时间戳
     * @param string $format 日期时间格式
     * @return string
     */
    function datetime($time, $format = 'Y-m-d H:i:s')
    {
        $time = is_numeric($time) ? $time : strtotime($time);
        return date($format, $time);
    }
}

if (!function_exists('human_date')) {

    /**
     * 获取语义化时间
     * @param int $time  时间
     * @param int $local 本地时间
     * @return string
     */
    function human_date($time, $local = null)
    {
        return \fast\Date::human($time, $local);
    }
}

function array2xml($arr, $level = 1) {
	$s = $level == 1 ? "<xml>" : '';
	foreach ($arr as $tagname => $value) {
		if (is_numeric($tagname)) {
			$tagname = $value['TagName'];
			unset($value['TagName']);
		}
		if (!is_array($value)) {
			$s .= "<{$tagname}>" . (!is_numeric($value) ? '<![CDATA[' : '') . $value . (!is_numeric($value) ? ']]>' : '') . "</{$tagname}>";
		} else {
			$s .= "<{$tagname}>" . array2xml($value, $level + 1) . "</{$tagname}>";
		}
	}
	$s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
	return $level == 1 ? $s . "</xml>" : $s;
}

if (!function_exists('cdnurl')) { 

    /**
     * 获取上传资源的CDN的地址
     * @param string  $url    资源相对地址
     * @param boolean $domain 是否显示域名 或者直接传入域名
     * @return string
     */
    function cdnurl($url, $domain = false)
    {
        global $_W;
        if(empty($url)){
            return "";
        }

        if(strstr($url, 'http')){
            return $url;
        }
        
        $regex = "/^((?:[a-z]+:)?\/\/|data:image\/)(.*)/i";
        // $cdnurl = \think\Config::get('upload.cdnurl');
        $cdnurl = "";
        if(!empty($_W['base']['data']) && !empty($_W['base']['data']['aliyun_oss']) && !empty($_W['base']['data']['aliyun_oss']['cdnurl'])){
            if($_W['base']['data']['aliyun_oss']['type'] != 1){
                $cdnurl = $_W['base']['data']['aliyun_oss']['cdnurl'];
            }
        }
        

        if(preg_match($regex, $url)){
            return $url;
        }

        $domain_url = request()->domain();
        if(empty($domain_url) || $domain_url == 'http://' || $domain_url == 'https://'){
            $domain_url = "";
            $ym = Cache::get("bbfx_domain");
            if(!empty($ym)){
                $domain_url = "https://".$ym;
            }
            
        }

        if($domain){
            $domain = is_bool($domain) ? $domain_url : $domain;
            if(!$domain) return $url;
            $url = $domain . $url;
        }
        else{
            if(!empty($cdnurl)){
                $url = $cdnurl . $url;
            }
            else{
                $attachment_list = Cache::get("attachment_list");
                if(!empty($attachment_list) && !empty($attachment_list[$url])){
                    $url = "https://".$attachment_list[$url]['oss_domain'] . $url;
                }
                else{
                    if(!$domain_url) return $url;
                    $url = $domain_url . $url;
                }
            }
            
        }

        return $url;
    }
}


if (!function_exists('is_really_writable')) {

    /**
     * 判断文件或文件夹是否可写
     * @param string $file 文件或目录
     * @return    bool
     */
    function is_really_writable($file)
    {
        if (DIRECTORY_SEPARATOR === '/') {
            return is_writable($file);
        }
        if (is_dir($file)) {
            $file = rtrim($file, '/') . '/' . md5(mt_rand());
            if (($fp = @fopen($file, 'ab')) === false) {
                return false;
            }
            fclose($fp);
            @chmod($file, 0777);
            @unlink($file);
            return true;
        } elseif (!is_file($file) or ($fp = @fopen($file, 'ab')) === false) {
            return false;
        }
        fclose($fp);
        return true;
    }
}

if (!function_exists('rmdirs')) {

    /**
     * 删除文件夹
     * @param string $dirname  目录
     * @param bool   $withself 是否删除自身
     * @return boolean
     */
    function rmdirs($dirname, $withself = true)
    {
        if (!is_dir($dirname)) {
            return false;
        }
        $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::CHILD_FIRST
        );

        foreach ($files as $fileinfo) {
            $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
            $todo($fileinfo->getRealPath());
        }
        if ($withself) {
            @rmdir($dirname);
        }
        return true;
    }
}

if (!function_exists('copydirs')) {

    /**
     * 复制文件夹
     * @param string $source 源文件夹
     * @param string $dest   目标文件夹
     */
    function copydirs($source, $dest)
    {
        if (!is_dir($dest)) {
            mkdir($dest, 0755, true);
        }
        foreach (
            $iterator = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
                RecursiveIteratorIterator::SELF_FIRST
            ) as $item
        ) {
            if ($item->isDir()) {
                $sontDir = $dest . DS . $iterator->getSubPathName();
                if (!is_dir($sontDir)) {
                    mkdir($sontDir, 0755, true);
                }
            } else {
                copy($item, $dest . DS . $iterator->getSubPathName());
            }
        }
    }
}

if (!function_exists('mb_ucfirst')) {
    function mb_ucfirst($string)
    {
        return mb_strtoupper(mb_substr($string, 0, 1)) . mb_strtolower(mb_substr($string, 1));
    }
}

if (!function_exists('addtion')) {

    /**
     * 附加关联字段数据
     * @param array $items  数据列表
     * @param mixed $fields 渲染的来源字段
     * @return array
     */
    function addtion($items, $fields)
    {
        if (!$items || !$fields) {
            return $items;
        }
        $fieldsArr = [];
        if (!is_array($fields)) {
            $arr = explode(',', $fields);
            foreach ($arr as $k => $v) {
                $fieldsArr[$v] = ['field' => $v];
            }
        } else {
            foreach ($fields as $k => $v) {
                if (is_array($v)) {
                    $v['field'] = $v['field'] ?? $k;
                } else {
                    $v = ['field' => $v];
                }
                $fieldsArr[$v['field']] = $v;
            }
        }
        foreach ($fieldsArr as $k => &$v) {
            $v = is_array($v) ? $v : ['field' => $v];
            $v['display'] = $v['display'] ?? str_replace(['_ids', '_id'], ['_names', '_name'], $v['field']);
            $v['primary'] = $v['primary'] ?? '';
            $v['column'] = $v['column'] ?? 'name';
            $v['model'] = $v['model'] ?? '';
            $v['table'] = $v['table'] ?? '';
            $v['name'] = $v['name'] ?? str_replace(['_ids', '_id'], '', $v['field']);
        }
        unset($v);
        $ids = [];
        $fields = array_keys($fieldsArr);
        foreach ($items as $k => $v) {
            foreach ($fields as $m => $n) {
                if (isset($v[$n])) {
                    $ids[$n] = array_merge(isset($ids[$n]) && is_array($ids[$n]) ? $ids[$n] : [], explode(',', $v[$n]));
                }
            }
        }
        $result = [];
        foreach ($fieldsArr as $k => $v) {
            if ($v['model']) {
                $model = new $v['model'];
            } else {
                $model = $v['name'] ? \think\Db::name($v['name']) : \think\Db::table($v['table']);
            }
            $primary = $v['primary'] ? $v['primary'] : $model->getPk();
            $result[$v['field']] = isset($ids[$v['field']]) ? $model->where($primary, 'in', $ids[$v['field']])->column($v['column'], $primary) : [];
        }

        foreach ($items as $k => &$v) {
            foreach ($fields as $m => $n) {
                if (isset($v[$n])) {
                    $curr = array_flip(explode(',', $v[$n]));

                    $linedata = array_intersect_key($result[$n], $curr);
                    $v[$fieldsArr[$n]['display']] = $fieldsArr[$n]['column'] == '*' ? $linedata : implode(',', $linedata);
                }
            }
        }
        return $items;
    }
}

if (!function_exists('var_export_short')) {

    /**
     * 使用短标签打印或返回数组结构
     * @param mixed   $data
     * @param boolean $return 是否返回数据
     * @return string
     */
    function var_export_short($data, $return = true)
    {
        return var_export($data, $return);
        $replaced = [];
        $count = 0;

        //判断是否是对象
        if (is_resource($data) || is_object($data)) {
            return var_export($data, $return);
        }

        //判断是否有特殊的键名
        $specialKey = false;
        array_walk_recursive($data, function (&$value, &$key) use (&$specialKey) {
            if (is_string($key) && (stripos($key, "\n") !== false || stripos($key, "array (") !== false)) {
                $specialKey = true;
            }
        });
        if ($specialKey) {
            return var_export($data, $return);
        }
        array_walk_recursive($data, function (&$value, &$key) use (&$replaced, &$count, &$stringcheck) {
            if (is_object($value) || is_resource($value)) {
                $replaced[$count] = var_export($value, true);
                $value = "##<{$count}>##";
            } else {
                if (is_string($value) && (stripos($value, "\n") !== false || stripos($value, "array (") !== false)) {
                    $index = array_search($value, $replaced);
                    if ($index === false) {
                        $replaced[$count] = var_export($value, true);
                        $value = "##<{$count}>##";
                    } else {
                        $value = "##<{$index}>##";
                    }
                }
            }
            $count++;
        });

        $dump = var_export($data, true);

        $dump = preg_replace('#(?:\A|\n)([ ]*)array \(#i', '[', $dump); // Starts
        $dump = preg_replace('#\n([ ]*)\),#', "\n$1],", $dump); // Ends
        $dump = preg_replace('#=> \[\n\s+\],\n#', "=> [],\n", $dump); // Empties
        $dump = preg_replace('#\)$#', "]", $dump); //End

        if ($replaced) {
            $dump = preg_replace_callback("/'##<(\d+)>##'/", function ($matches) use ($replaced) {
                return $replaced[$matches[1]] ?? "''";
            }, $dump);
        }

        if ($return === true) {
            return $dump;
        } else {
            echo $dump;
        }
    }
}

if (!function_exists('letter_avatar')) {
    /**
     * 首字母头像
     * @param $text
     * @return string
     */
    function letter_avatar($text)
    {
        $total = unpack('L', hash('adler32', $text, true))[1];
        $hue = $total % 360;
        list($r, $g, $b) = hsv2rgb($hue / 360, 0.3, 0.9);

        $bg = "rgb({$r},{$g},{$b})";
        $color = "#ffffff";
        $first = mb_strtoupper(mb_substr($text, 0, 1));
        $src = base64_encode('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="100" width="100"><rect fill="' . $bg . '" x="0" y="0" width="100" height="100"></rect><text x="50" y="50" font-size="50" text-copy="fast" fill="' . $color . '" text-anchor="middle" text-rights="admin" dominant-baseline="central">' . $first . '</text></svg>');
        $value = 'data:image/svg+xml;base64,' . $src;
        return $value;
    }
}

if (!function_exists('hsv2rgb')) {
    function hsv2rgb($h, $s, $v)
    {
        $r = $g = $b = 0;

        $i = floor($h * 6);
        $f = $h * 6 - $i;
        $p = $v * (1 - $s);
        $q = $v * (1 - $f * $s);
        $t = $v * (1 - (1 - $f) * $s);

        switch ($i % 6) {
            case 0:
                $r = $v;
                $g = $t;
                $b = $p;
                break;
            case 1:
                $r = $q;
                $g = $v;
                $b = $p;
                break;
            case 2:
                $r = $p;
                $g = $v;
                $b = $t;
                break;
            case 3:
                $r = $p;
                $g = $q;
                $b = $v;
                break;
            case 4:
                $r = $t;
                $g = $p;
                $b = $v;
                break;
            case 5:
                $r = $v;
                $g = $p;
                $b = $q;
                break;
        }

        return [
            floor($r * 255),
            floor($g * 255),
            floor($b * 255)
        ];
    }
}

if (!function_exists('check_nav_active')) {
    /**
     * 检测会员中心导航是否高亮
     */
    function check_nav_active($url, $classname = 'active')
    {
        $auth = \app\common\library\Auth::instance();
        $requestUrl = $auth->getRequestUri();
        $url = ltrim($url, '/');
        return $requestUrl === str_replace(".", "/", $url) ? $classname : '';
    }
}

if (!function_exists('check_cors_request')) {
    /**
     * 跨域检测
     */
    function check_cors_request()
    {
        if (isset($_SERVER['HTTP_ORIGIN']) && $_SERVER['HTTP_ORIGIN'] && config('fastadmin.cors_request_domain')) {
            $info = parse_url($_SERVER['HTTP_ORIGIN']);
            $domainArr = explode(',', config('fastadmin.cors_request_domain'));
            $domainArr[] = request()->host(true);
            if (in_array("*", $domainArr) || in_array($_SERVER['HTTP_ORIGIN'], $domainArr) || (isset($info['host']) && in_array($info['host'], $domainArr))) {
                header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
            } else {
                $response = Response::create('跨域检测无效', 'html', 403);
                throw new HttpResponseException($response);
            }

            header('Access-Control-Allow-Credentials: true');
            header('Access-Control-Max-Age: 86400');

            if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
                if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
                    header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
                }
                if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) {
                    header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
                }
                $response = Response::create('', 'html');
                throw new HttpResponseException($response);
            }
        }
    }
}

if (!function_exists('xss_clean')) {
    /**
     * 清理XSS
     */
    function xss_clean($content, $is_image = false)
    {
        return \app\common\library\Security::instance()->xss_clean($content, $is_image);
    }
}

if (!function_exists('url_clean')) {
    /**
     * 清理URL
     */
    function url_clean($url)
    {
        if (!check_url_allowed($url)) {
            return '';
        }
        return xss_clean($url);
    }
}

if (!function_exists('check_ip_allowed')) {
    /**
     * 检测IP是否允许
     * @param string $ip IP地址
     */
    function check_ip_allowed($ip = null)
    {
        $ip = is_null($ip) ? request()->ip() : $ip;
        $forbiddenipArr = config('site.forbiddenip');
        $forbiddenipArr = !$forbiddenipArr ? [] : $forbiddenipArr;
        $forbiddenipArr = is_array($forbiddenipArr) ? $forbiddenipArr : array_filter(explode("\n", str_replace("\r\n", "\n", $forbiddenipArr)));
        if ($forbiddenipArr && \Symfony\Component\HttpFoundation\IpUtils::checkIp($ip, $forbiddenipArr)) {
            $response = Response::create('请求无权访问', 'html', 403);
            throw new HttpResponseException($response);
        }
    }
}

if (!function_exists('check_url_allowed')) {
    /**
     * 检测URL是否允许
     * @param string $url URL
     * @return bool
     */
    function check_url_allowed($url = '')
    {
        //允许的主机列表
        $allowedHostArr = [
            strtolower(request()->host())
        ];

        if (empty($url)) {
            return true;
        }

        //如果是站内相对链接则允许
        if (preg_match("/^[\/a-z][a-z0-9][a-z0-9\.\/]+((\?|#).*)?\$/i", $url) && substr($url, 0, 2) !== '//') {
            return true;
        }

        //如果是站外链接则需要判断HOST是否允许
        if (preg_match("/((http[s]?:\/\/)+(?>[a-z\-0-9]{2,}\.){1,}[a-z]{2,8})(?:\s|\/)/i", $url)) {
            $chkHost = parse_url(strtolower($url), PHP_URL_HOST);
            if ($chkHost && in_array($chkHost, $allowedHostArr)) {
                return true;
            }
        }

        return false;
    }
}

if (!function_exists('build_suffix_image')) {
    /**
     * 生成文件后缀图片
     * @param string $suffix 后缀
     * @param null   $background
     * @return string
     */
    function build_suffix_image($suffix, $background = null)
    {
        $suffix = mb_substr(strtoupper($suffix), 0, 4);
        $total = unpack('L', hash('adler32', $suffix, true))[1];
        $hue = $total % 360;
        list($r, $g, $b) = hsv2rgb($hue / 360, 0.3, 0.9);

        $background = $background ? $background : "rgb({$r},{$g},{$b})";

        $icon = <<<EOT
        <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
            <path style="fill:#E2E5E7;" d="M128,0c-17.6,0-32,14.4-32,32v448c0,17.6,14.4,32,32,32h320c17.6,0,32-14.4,32-32V128L352,0H128z"/>
            <path style="fill:#B0B7BD;" d="M384,128h96L352,0v96C352,113.6,366.4,128,384,128z"/>
            <polygon style="fill:#CAD1D8;" points="480,224 384,128 480,128 "/>
            <path style="fill:{$background};" d="M416,416c0,8.8-7.2,16-16,16H48c-8.8,0-16-7.2-16-16V256c0-8.8,7.2-16,16-16h352c8.8,0,16,7.2,16,16 V416z"/>
            <path style="fill:#CAD1D8;" d="M400,432H96v16h304c8.8,0,16-7.2,16-16v-16C416,424.8,408.8,432,400,432z"/>
            <g><text><tspan x="220" y="380" font-size="124" font-family="Verdana, Helvetica, Arial, sans-serif" fill="white" text-anchor="middle">{$suffix}</tspan></text></g>
        </svg>
EOT;
        return $icon;
    }
}


function random($length, $numeric = FALSE) {
	$seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
	$seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed));
	if ($numeric) {
		$hash = '';
	} else {
		$hash = chr(rand(1, 26) + rand(0, 1) * 32 + 64);
		$length--;
	}
	$max = strlen($seed) - 1;
	for ($i = 0; $i < $length; $i++) {
		$hash .= $seed[mt_rand(0, $max)];
	}
	return $hash;
}

function isimplexml_load_string($string, $class_name = 'SimpleXMLElement', $options = 0, $ns = '', $is_prefix = false) {
	libxml_disable_entity_loader(true);
	if (preg_match('/(\<\!DOCTYPE|\<\!ENTITY)/i', $string)) {
		return false;
	}
	return simplexml_load_string($string, $class_name, $options, $ns, $is_prefix);
}

function ihttp_get($url) {
	return ihttp_request($url);
}

function ihttp_post($url, $data,$headers=[]) {
    if(empty($headers)){
        $headers = array('Content-Type' => 'application/x-www-form-urlencoded');
    }
	return ihttp_request($url, $data, $headers);
}

function ihttp_request($url, $post = '', $extra = array(), $timeout = 60) {
    error_reporting(0);
			if (function_exists('curl_init') && function_exists('curl_exec') && $timeout > 0) {
		$ch = ihttp_build_curl($url, $post, $extra, $timeout);
		if (is_error($ch)) {
			return $ch;
		}
		$data = curl_exec($ch);
		$status = curl_getinfo($ch);
		$errno = curl_errno($ch);
		$error = curl_error($ch);
		curl_close($ch);
		if ($errno || empty($data)) {
			return error($errno, $error);
		} else {
			return ihttp_response_parse($data);
		}
	}
	$urlset = ihttp_parse_url($url, true);
	if (!empty($urlset['ip'])) {
		$urlset['host'] = $urlset['ip'];
	}

	$body = ihttp_build_httpbody($url, $post, $extra);

	if ($urlset['scheme'] == 'https') {
		$fp = ihttp_socketopen('ssl://' . $urlset['host'], $urlset['port'], $errno, $error);
	} else {
		$fp = ihttp_socketopen($urlset['host'], $urlset['port'], $errno, $error);
	}
	stream_set_blocking($fp, $timeout > 0 ? true : false);
	stream_set_timeout($fp, ini_get('default_socket_timeout'));
	if (!$fp) {
		return error(1, $error);
	} else {
		fwrite($fp, $body);
		$content = '';
		if($timeout > 0) {
			while (!feof($fp)) {
				$content .= fgets($fp, 512);
			}
		}
		fclose($fp);
		return ihttp_response_parse($content, true);
	}
}

function error($errno, $message = '') {
	return array(
		'code' => $errno,
		'msg' => $message,
	);
}


function is_error($data) {
	if (empty($data) || !is_array($data) || !array_key_exists('code', $data) || (array_key_exists('code', $data) && $data['code'] == 0)) {
		return false;
	} else {
		return true;
	}
}

function strexists($string, $find) {
	return !(strpos($string, $find) === FALSE);
}

function ihttp_socketopen($hostname, $port = 80, &$errno, &$errstr, $timeout = 15) {
	$fp = '';
	if(function_exists('fsockopen')) {
		$fp = @fsockopen($hostname, $port, $errno, $errstr, $timeout);
	} elseif(function_exists('pfsockopen')) {
		$fp = @pfsockopen($hostname, $port, $errno, $errstr, $timeout);
	} elseif(function_exists('stream_socket_client')) {
		$fp = @stream_socket_client($hostname.':'.$port, $errno, $errstr, $timeout);
	}
	return $fp;
}

function ihttp_build_httpbody($url, $post, $extra) {
	$urlset = ihttp_parse_url($url, true);
	if (is_error($urlset)) {
		return $urlset;
	}

	if (!empty($urlset['ip'])) {
		$extra['ip'] = $urlset['ip'];
	}

	$body = '';
	if (!empty($post) && is_array($post)) {
		$filepost = false;
		$boundary = random(40);
		foreach ($post as $name => &$value) {
			if ((is_string($value) && substr($value, 0, 1) == '@') && file_exists(ltrim($value, '@'))) {
				$filepost = true;
				$file = ltrim($value, '@');

				$body .= "--$boundary\r\n";
				$body .= 'Content-Disposition: form-data; name="'.$name.'"; filename="'.basename($file).'"; Content-Type: application/octet-stream'."\r\n\r\n";
				$body .= file_get_contents($file)."\r\n";
			} else {
				$body .= "--$boundary\r\n";
				$body .= 'Content-Disposition: form-data; name="'.$name.'"'."\r\n\r\n";
				$body .= $value."\r\n";
			}
		}
		if (!$filepost) {
			$body = http_build_query($post, '', '&');
		} else {
			$body .= "--$boundary\r\n";
		}
	}

	$method = empty($post) ? 'GET' : 'POST';
	$fdata = "{$method} {$urlset['path']}{$urlset['query']} HTTP/1.1\r\n";
	$fdata .= "Accept: */*\r\n";
	$fdata .= "Accept-Language: zh-cn\r\n";
	if ($method == 'POST') {
		$fdata .= empty($filepost) ? "Content-Type: application/x-www-form-urlencoded\r\n" : "Content-Type: multipart/form-data; boundary=$boundary\r\n";
	}
	$fdata .= "Host: {$urlset['host']}\r\n";
	$fdata .= "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1\r\n";
	if (function_exists('gzdecode')) {
		$fdata .= "Accept-Encoding: gzip, deflate\r\n";
	}
	$fdata .= "Connection: close\r\n";
	if (!empty($extra) && is_array($extra)) {
		foreach ($extra as $opt => $value) {
			if (!strexists($opt, 'CURLOPT_')) {
				$fdata .= "{$opt}: {$value}\r\n";
			}
		}
	}
	if ($body) {
		$fdata .= 'Content-Length: ' . strlen($body) . "\r\n\r\n{$body}";
	} else {
		$fdata .= "\r\n";
	}
	return $fdata;
}

function ihttp_allow_host($host) {
	global $_W;
	if (strexists($host, '@')) {
		return false;
	}
	$pattern = "/^(10|172|192|127)/";
	if (preg_match($pattern, $host) && isset($_W['setting']['ip_white_list'])) {
		$ip_white_list = $_W['setting']['ip_white_list'];
		if ($ip_white_list && isset($ip_white_list[$host]) && !$ip_white_list[$host]['status']) {
			return false;
		}
	}
	return true;
}

function ihttp_parse_url($url, $set_default_port = false) {
	if (empty($url)) {
		return error(1);
	}
	$urlset = parse_url($url);
	if (!empty($urlset['scheme']) && !in_array($urlset['scheme'], array('http', 'https'))) {
		return error(1, '只能使用 http 及 https 协议');
	}
	if (empty($urlset['path'])) {
		$urlset['path'] = '/';
	}
	if (!empty($urlset['query'])) {
		$urlset['query'] = "?{$urlset['query']}";
	}
	if (strexists($url, 'https://') && !extension_loaded('openssl')) {
		if (!extension_loaded("openssl")) {
			return error(1,'请开启您PHP环境的openssl', '');
		}
	}
	if (empty($urlset['host'])) {
		$current_url = parse_url($GLOBALS['_W']['siteroot']);
		$urlset['host'] = $current_url['host'];
		$urlset['scheme'] = $current_url['scheme'];
		$urlset['path'] = $current_url['path'] . 'web/' . str_replace('./', '', $urlset['path']);
		$urlset['ip'] = '127.0.0.1';
	} else if (! ihttp_allow_host($urlset['host'])){
		return error(1, 'host 非法');
	}

	if ($set_default_port && empty($urlset['port'])) {
		$urlset['port'] = $urlset['scheme'] == 'https' ? '443' : '80';
	}
	return $urlset;
}

function ihttp_response_parse($data, $chunked = false) {
	$rlt = array();

	$headermeta = explode('HTTP/', $data);
	if (count($headermeta) > 2) {
		$data = 'HTTP/' . array_pop($headermeta);
	}
	$pos = strpos($data, "\r\n\r\n");
	$split1[0] = substr($data, 0, $pos);
	$split1[1] = substr($data, $pos + 4, strlen($data));

	$split2 = explode("\r\n", $split1[0], 2);
	preg_match('/^(\S+) (\S+) (.*)$/', $split2[0], $matches);
	$rlt['code'] = !empty($matches[2]) ? $matches[2] : 200;
	$rlt['status'] = !empty($matches[3]) ? $matches[3] : 'OK';
	$rlt['responseline'] = !empty($split2[0]) ? $split2[0] : '';
	$header = explode("\r\n", $split2[1]);
	$isgzip = false;
	$ischunk = false;
	foreach ($header as $v) {
		$pos = strpos($v, ':');
		$key = substr($v, 0, $pos);
		$value = trim(substr($v, $pos + 1));
		if (!empty($rlt['headers']) && is_array($rlt['headers'][$key])) {
			$rlt['headers'][$key][] = $value;
		} elseif (!empty($rlt['headers'][$key])) {
			$temp = $rlt['headers'][$key];
			unset($rlt['headers'][$key]);
			$rlt['headers'][$key][] = $temp;
			$rlt['headers'][$key][] = $value;
		} else {
			$rlt['headers'][$key] = $value;
		}
		if(!$isgzip && strtolower($key) == 'content-encoding' && strtolower($value) == 'gzip') {
			$isgzip = true;
		}
		if(!$ischunk && strtolower($key) == 'transfer-encoding' && strtolower($value) == 'chunked') {
			$ischunk = true;
		}
	}
	if($chunked && $ischunk) {
		$rlt['content'] = ihttp_response_parse_unchunk($split1[1]);
	} else {
		$rlt['content'] = $split1[1];
	}
	if($isgzip && function_exists('gzdecode')) {
		$rlt['content'] = gzdecode($rlt['content']);
	}

	$rlt['meta'] = $data;
	if($rlt['code'] == '100') {
		return ihttp_response_parse($rlt['content']);
	}
	return $rlt;
}

function ihttp_response_parse_unchunk($str = null) {
	if(!is_string($str) or strlen($str) < 1) {
		return false;
	}
	$eol = "\r\n";
	$add = strlen($eol);
	$tmp = $str;
	$str = '';
	do {
		$tmp = ltrim($tmp);
		$pos = strpos($tmp, $eol);
		if($pos === false) {
			return false;
		}
		$len = hexdec(substr($tmp, 0, $pos));
		if(!is_numeric($len) or $len < 0) {
			return false;
		}
		$str .= substr($tmp, ($pos + $add), $len);
		$tmp  = substr($tmp, ($len + $pos + $add));
		$check = trim($tmp);
	} while(!empty($check));
	unset($tmp);
	return $str;
}

function ihttp_build_curl($url, $post, $extra, $timeout) {
	if (!function_exists('curl_init') || !function_exists('curl_exec')) {
		return error(1, 'curl扩展未开启');
	}

	$urlset = ihttp_parse_url($url);
	if (is_error($urlset)) {
		return $urlset;
	}

	if (!empty($urlset['ip'])) {
		$extra['ip'] = $urlset['ip'];
	}

	$ch = curl_init();
	if (!empty($extra['ip'])) {
		$extra['Host'] = $urlset['host'];
		$urlset['host'] = $extra['ip'];
		unset($extra['ip']);
	}
	if(empty($urlset['query'])){
	    $urlset['query'] = "";
	}
	curl_setopt($ch, CURLOPT_URL, $urlset['scheme'] . '://' . $urlset['host'] . (!empty($urlset['port']) && $urlset['port'] == '80' || empty($urlset['port']) ? '' : ':' . $urlset['port']) . $urlset['path'] . $urlset['query']);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_HEADER, 1);
	@curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
	if ($post) {
		if (is_array($post)) {
			$filepost = false;
						foreach ($post as $name => &$value) {
				if (version_compare(phpversion(), '5.5') >= 0 && is_string($value) && substr($value, 0, 1) == '@') {
					$post[$name] = new CURLFile(ltrim($value, '@'));
				}
				if ((is_string($value) && substr($value, 0, 1) == '@') || (class_exists('CURLFile') && $value instanceof CURLFile)) {
					$filepost = true;
				}
			}
			if (!$filepost) {
				$post = http_build_query($post);
			}
		}
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
	}
	if (!empty($GLOBALS['_W']['config']['setting']['proxy'])) {
		$urls = parse_url($GLOBALS['_W']['config']['setting']['proxy']['host']);
		if (!empty($urls['host'])) {
			curl_setopt($ch, CURLOPT_PROXY, "{$urls['host']}:{$urls['port']}");
			$proxytype = 'CURLPROXY_' . strtoupper($urls['scheme']);
			if (!empty($urls['scheme']) && defined($proxytype)) {
				curl_setopt($ch, CURLOPT_PROXYTYPE, constant($proxytype));
			} else {
				curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
				curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
			}
			if (!empty($GLOBALS['_W']['config']['setting']['proxy']['auth'])) {
				curl_setopt($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['_W']['config']['setting']['proxy']['auth']);
			}
		}
	}
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
	curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
	curl_setopt($ch, CURLOPT_SSLVERSION, 1);
	if (defined('CURL_SSLVERSION_TLSv1')) {
		curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
	}
	curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1');
	if (!empty($extra) && is_array($extra)) {
		$headers = array();
		foreach ($extra as $opt => $value) {
			if (strexists($opt, 'CURLOPT_')) {
				curl_setopt($ch, constant($opt), $value);
			} elseif (is_numeric($opt)) {
				curl_setopt($ch, $opt, $value);
			} else {
				$headers[] = "{$opt}: {$value}";
			}
		}
		if (!empty($headers)) {
			curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		}
	}
	return $ch;
}
