<?php

namespace Our;

class Common
{
    public static $requestTime;

    /**
     * 获取http状态码
     *
     * @param int $num
     * @return string
     */
    public static function getHttpStatusCode($num)
    {
        $httpStatusCodes = array(
            100 => "HTTP/1.1 100 Continue",
            101 => "HTTP/1.1 101 Switching Protocols",
            200 => "HTTP/1.1 200 OK",
            201 => "HTTP/1.1 201 Created",
            202 => "HTTP/1.1 202 Accepted",
            203 => "HTTP/1.1 203 Non-Authoritative Information",
            204 => "HTTP/1.1 204 No Content",
            205 => "HTTP/1.1 205 Reset Content",
            206 => "HTTP/1.1 206 Partial Content",
            300 => "HTTP/1.1 300 Multiple Choices",
            301 => "HTTP/1.1 301 Moved Permanently",
            302 => "HTTP/1.1 302 Found",
            303 => "HTTP/1.1 303 See Other",
            304 => "HTTP/1.1 304 Not Modified",
            305 => "HTTP/1.1 305 Use Proxy",
            307 => "HTTP/1.1 307 Temporary Redirect",
            400 => "HTTP/1.1 400 Bad Request",
            401 => "HTTP/1.1 401 Unauthorized",
            402 => "HTTP/1.1 402 Payment Required",
            403 => "HTTP/1.1 403 Forbidden",
            404 => "HTTP/1.1 404 Not Found",
            405 => "HTTP/1.1 405 Method Not Allowed",
            406 => "HTTP/1.1 406 Not Acceptable",
            407 => "HTTP/1.1 407 Proxy Authentication Required",
            408 => "HTTP/1.1 408 Request Time-out",
            409 => "HTTP/1.1 409 Conflict",
            410 => "HTTP/1.1 410 Gone",
            411 => "HTTP/1.1 411 Length Required",
            412 => "HTTP/1.1 412 Precondition Failed",
            413 => "HTTP/1.1 413 Request Entity Too Large",
            414 => "HTTP/1.1 414 Request-URI Too Large",
            415 => "HTTP/1.1 415 Unsupported Media Type",
            416 => "HTTP/1.1 416 Requested range not satisfiable",
            417 => "HTTP/1.1 417 Expectation Failed",
            500 => "HTTP/1.1 500 Internal Server Error",
            501 => "HTTP/1.1 501 Not Implemented",
            502 => "HTTP/1.1 502 Bad Gateway",
            503 => "HTTP/1.1 503 Service Unavailable",
            504 => "HTTP/1.1 504 Gateway Time-out"
        );

        return isset($httpStatusCodes[$num]) ? $httpStatusCodes[$num] : '';
    }

    public static function isCurentTimeInSection($begin, $end)
    {
        $checkDayStr = date('Y-m-d ', time());
        $timeBegin1 = strtotime($checkDayStr . $begin . ":00");
        $timeEnd1 = strtotime($checkDayStr . $end . ":00");
        $curr_time = time();
        if ($curr_time >= $timeBegin1 && $curr_time <= $timeEnd1) {
            return true;
        }
        return false;
    }
    /**
     * @param $arr
     * @param $key_name
     * @return array
     * 将数据库中查出的列表以指定的 id 作为数组的键名
     */
public static function convertArrKey($arr, $key_name)
    {
        $arr2 = array();
        foreach ($arr as $key => $val) {
            $arr2[$val[$key_name]] = $val;
        }
        return $arr2;
    }

    public static function isSerialized($data)
    {
        $data = trim($data);
        if ('N;' == $data)
            return true;
        if (!preg_match('/^([adObis]):/', $data, $badions))
            return false;
        switch ($badions[1]) {
            case 'a' :
            case 'O' :
            case 's' :
                if (preg_match("/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data))
                    return true;
                break;
            case 'b' :
            case 'i' :
            case 'd' :
                if (preg_match("/^{$badions[1]}:[0-9.E-]+;\$/", $data))
                    return true;
                break;
        }
        return false;
    }
   public static function redisPublish($control,$method,$params){
       //发布application.redis.redisPublishName
       $conf = \Yaf\Registry::get('config')->get('redis.database.params');
       $redisPublishName=\Yaf\Registry::get('config')->get('redis.redisPublishName');
       $redis=new \Redis();
       $redis->connect($conf['host'], $conf['port']);
       if(!empty($conf['password'])){
           $redis->auth($conf['password']);
       }
       $message['className']=$control;
       $message['method']=$method;
       $message['params']=$params;
       $message=json_encode($message);
       $ret=$redis->publish($redisPublishName,$message);
       return $ret;
   }
    /**
     * 获取客户端IP
     *
     * @param  boolean $checkProxy
     * @return string
     */
    public static function getClientIp($checkProxy = true)
    {
        if ($checkProxy && isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP'] != null) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } else if ($checkProxy && isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != null) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }

        return $ip;
    }

    /**
     * 获取当前访问的url地址
     *
     * @return string
     */
    public static function getRequestUrl()
    {
        return 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    }

    public static function getConfig($key)
    {
        $config = \Yaf\Registry::get('config');
        $configValue = $config->get($key);
        return $configValue;
    }

    public static function getBaseUrl()
    {
        $prefix = 'http';
        if (self::is_https()) {
            $prefix = 'https';
        }
        $url = $prefix . '://' . $_SERVER['SERVER_NAME'];
        return $url;
    }


    public static function is_https()
    {
        if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
            return true;
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
            return true;
        } elseif (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
            return true;
        } elseif ($_SERVER['SERVER_PORT'] == 89) {
            return true;
        }

        return false;
    }

    /**
     * 获取静态资源文件
     *
     * @param unknown_type $filename
     */
    public static function getStaticFile($filename, $directory = 'image/', $urlName = 'ossHost')
    {
        $files = array();
        $static = array();
        if (is_array($filename)) {
            $files = $filename;
        } elseif (is_string($filename)) {
            $files [] = $filename;
        }
        if (!empty ($files)) {
            foreach ($files as $file) {
                $timemap = '';
                if (strpos($file, '?') !== false) {
                    list ($file, $timemap) = explode('?', $file);
                    $timemap = empty($timemap) ? '' : '?' . $timemap;
                }
                $ext = strrchr($file, '.');
                $base = substr($file, 0, strlen($ext));
                $static [$ext] [] = $file . $timemap;
            }
        }
        //静态支援url
        $staticUrl = \Bootstrap::getUrlIniConfig($urlName);///($request_type == 'SSL') ? HTTPS_SERVER : ( G_IS_CN_IP ? G_HTTP_HOST_TMART : G_STATIC_IMAGE_TMART_COM);
        if (!empty ($static)) {
            $output = '';
            foreach ($static as $ext => $files) {
                switch (strtolower($ext)) {
                    case '.css' :
                        foreach ($files as $f) {
                            $output .= $staticUrl . '/' . 'data/css/' . $f;
                        }
                        break;
                    case '.js' :
                        foreach ($files as $f) {
                            $output .= $staticUrl . '/' . 'data/jscript/' . $f;
                        }
                        break;
                    case '.jpeg':
                    case '.jpg' :
                    case '.gif' :
                    case '.png' :
                    case '.apk' :
                        foreach ($files as $f) {
                            $output = $staticUrl . '/' . $directory . $f;
                        }
                        break;
                    default:
                        foreach ($files as $f) {
                            $output = $staticUrl . '/' . $directory . $f . \Our\NameConst::jpgSuffix;
                        }
                        break;
                }
            }
        }
        return $output;
    }

    private static function createRequsetId()
    {
        $arr = array('2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'X', 'Y', 'Z');
        $arrString = Array($arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)], $arr[rand(0, 27)]);
        $time = date('ymd', time());
        //查看结果
        $requestId = $time . implode('', $arrString);
        return $requestId;
    }


    public static function generatePassword($length = 8)
    {
        // 密码字符集，可任意添加你需要的字符
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_ []{}<>~`+=,.;:/?|';
        $password = '';
        for ($i = 0; $i < $length; $i++) {
            // 这里提供两种字符获取方式
            // 第一种是使用 substr 截取$chars中的任意一位字符；
            // 第二种是取字符数组 $chars 的任意元素
            // $password .= substr($chars, mt_rand(0, strlen($chars) – 1), 1);
            $password .= $chars[mt_rand(0, strlen($chars) - 1)];
        }
        return $password;
    }

    /**
     * bulid AppToken
     */
    public static function bulidToken($mobilePhone = null, $password = null, $zenid = null, $iso = null)
    {
        $bassStr = self::getClientIp();
        if ($zenid) {
            $bassStr .= $zenid;
        }
        if ($iso) {
            $bassStr .= $zenid;
        }
        if (empty($mobilePhone) || empty($password)) {
            $md5Key = md5($bassStr . TIMESTAMP);
        } else {
            $md5Key = md5($bassStr . self::generatePassword(ApiConst::randLengh) . TIMESTAMP);
        }
        return $md5Key;
    }

    /**
     * 手机号码验证
     * @param unknown $phone
     * @return boolean
     */
    public static function checkMobilePhone($phone)
    {
        if (empty($phone)) {
            return false;
        }

        if (!preg_match('/^1[3456789]\d{9}$/', $phone)) {
            return false;
        }

        return true;
    }

    public static function getRealStr($originStr)
    {
        $result = str_replace(array("\r\n", "\r", "\n"), "", $originStr);
        $result = trim($result);
        return $result;
    }

    public static function getDivNum($num)
    {
        return bcdiv($num, 100, 2);
    }

    public static function mutiplicative($num)
    {
        return intval(bcmul($num, \Our\ApiConst::oneHandred));
    }

    public static function isJson($string)
    {
        json_decode($string);
        return (json_last_error() == JSON_ERROR_NONE);
    }
    public static function paramToJson($param)
    {
        $array = array();
        $paramArrs = explode('&', $param);
        foreach ($paramArrs as $paramArr) {
            $array[strstr($paramArr, '=', true)] = substr(strstr($paramArr, '='), 1);
        }
        return $array;
    }

    /**
     * sql字符串格式化
     * @param unknown $phone
     * @return boolean
     */
    public static function format()
    {
        $args = func_get_args();
        if (count($args) == 0) {
            return;
        }
        if (count($args) == 1) {
            return $args[0];
        }
        $str = array_shift($args);
        $str = preg_replace_callback('/\\{(0|[1-9]\\d*)\\}/', create_function('$match', '$args = ' . var_export($args, true) . '; return isset($args[$match[1]]) ? $args[$match[1]] : $match[0];'), $str);
        return $str;
    }

//
    public static function getDriverType($isstring = false)
    {
        $agent = strtolower($_SERVER['HTTP_USER_AGENT']);
//分析数据
        $is_wx = (strpos($agent, 'miniprogram') || strpos($agent, 'micromessenger')) ? true : false;
        $is_pc = (strpos($agent, 'windows nt')) ? true : false;
        $is_iphone = (strpos($agent, 'iphone')) ? true : false;
        $is_ipad = (strpos($agent, 'ipad')) ? true : false;
        //$is_android = (strpos($agent, 'android')) ? true : false;
//输出数据
        $driverType = ApiConst::adroidType;

        if ($is_pc) {
            $driverType = ApiConst::pcType;
        }
        if ($is_iphone) {
            $driverType = ApiConst::iphoneType;
        }
        if ($is_ipad) {
            $driverType = ApiConst::ipadType;
        }
        if ($is_wx) {
            $driverType = ApiConst::wxType;
        }
        if ($isstring) {
            switch ($driverType) {
                case ApiConst::pcType:
                    $driverType = NameConst::pc;
                    break;
                case ApiConst::iphoneType:
                    $driverType = NameConst::iphone;
                    break;
                case ApiConst::adroidType:
                    $driverType = NameConst::android;
                    break;
                case ApiConst::ipadType:
                    $driverType = NameConst::ipad;
                    break;
                default:
                    ApiConst::zero;
                    break;
            }
        }
        return $driverType;
    }


    public static function getIdentify()
    {
        return self::getClientIp() . '-' . self::getDriverType();
    }

    /**
     * 下划线转驼峰
     * @param $str
     * @return null|string|string[]
     */
    public static function underlineToHump($str)
    {
        $str = preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) {
            return strtoupper($matches[2]);
        }, $str);
        return $str;
    }

    /**
     * 驼峰转下划线
     */
    public static function humpToLine($str)
    {
        $str = preg_replace_callback('/([A-Z]{1})/', function ($matches) {
            return '_' . strtolower($matches[0]);
        }, $str);
        return $str;
    }

    public static function getTodayBeginTimpSpan()
    {
        $totayTimeSpan = strtotime(date('Y-m-d'));
        return $totayTimeSpan;
    }

    /**
     * 驼峰数组转下划线数组
     * @param array $data
     * @return array
     */
    public static function convertHump($data = array())
    {
        $result = [];
        if ($data) {
            foreach ($data as $key => $item) {
                if (is_array($item) || is_object($item)) {
                    $result[self::humpToLine($key)] = self::convertHump((array)$item);
                } else {
                    $result[self::humpToLine($key)] = $item;
                }
            }
        }
        return $result;
    }


    /**
     * 下划线数组转驼峰数组
     * @param array $data
     * @return array
     */
    public static function convertUnderline($data = array())
    {
        $result = [];
        if ($data) {
            foreach ($data as $key => $item) {
                if (is_array($item) || is_object($item)) {
                    $result[self::underlineToHump($key)] = self::convertUnderline((array)$item);
                } else {
                    $result[self::underlineToHump($key)] = $item;
                }
            }
        }
        return $result;
    }

///推送模块
    public static function sendTcpMessage($data, $uid = false)
    {

        $push = \Yaf\Registry::get("push");
        if ($push['open']) {
            $argv = $GLOBALS['argv'];
            $isDebug = isset($argv[1]) ? intval($argv[1]) : false;
            $message['data'] = $data;
            $message['uid'] = $uid;
            $message = json_encode($message);
            $message = $message . "\r\n";
            $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
            if (!@socket_connect($socket, $push['host'], $push['port'])) {
                return false;
            }
            // @socket_connect($socket, $push['host'], $push['port']) or die("推送连接失败");
            $num = 0;
            $length = strlen($message);
            do {
                $buffer = substr($message, $num);
                $ret = @socket_write($socket, $buffer);
                $num += $ret;
            } while ($num < $length);
            $ret = '';
            do {
                $buffer = @socket_read($socket, 1024, PHP_BINARY_READ);
                $ret .= $buffer;
            } while (strlen($buffer) == 1024);
            socket_close($socket);
            $server_data = json_decode($ret, true);
            if ($server_data['status'] == 1) {
                if ($isDebug) {
                    return true;
                }
            } else {
                if ($isDebug) {
                    return $server_data['data']['error_code'];
                }
            }
        } else {
            return false;
        }

    }

    public static function getSortArr($sortArray)
    {
        ksort($sortArray);
        $str = '';
        foreach ($sortArray as $val) {
            $str .= $val;
        }
        return $str;
    }

    //合并一对多列表
    public static function intergrateOneToMany($list1, $list2, $mergekey1, $mergekey2, $listName = 'orderGoods', $sortField = 'gmtUpdate')
    {
        $mergeArray = array();
        $list2key = array();
        foreach ($list1 as $value) {
            $list2key[$value[$mergekey1]] = $value;
        }
        $value[$listName] = array();
        foreach ($list2 as &$value) {
            if (isset($list2key[$value[$mergekey2]]) && !empty($list2key[$value[$mergekey2]])) {
                $list2key[$value[$mergekey2]][$listName][] = $value;
            }
        }
        $orders = array_values($list2key);
        array_multisort(array_column($orders, $sortField), SORT_DESC, $orders);
        return $orders;
    }
//    //合并一对多列表
//    public static function intergrateOneToMany($list1,$list2,$mergekey1,$mergekey2,$listName='orderGoods'){
//        $mergeArray=array();
//        $list2key=array();
//        foreach($list2 as $value){
//            $list2key[$value[$mergekey2]]=$value;
//        }
//        $value[$listName]=array();
//        foreach($list1 as &$value){
//            if(isset($list2key[$value[$mergekey1]])&&!empty($list2key[$value[$mergekey1]])){
//                $value[$listName][]=$list2key[$value[$mergekey1]];
//            }
//            array_push($mergeArray,$value);
//        }
//        return $mergeArray;
//    }
    //合并一对一数组
    //合并一对多列表
    public static function intergrateOneToOne($list1, $list2, $mergekey1, $mergekey2)
    {
        $mergeArray = array();
        $list2key = array();
        foreach ($list2 as $value) {
            $list2key[$value[$mergekey2]] = $value;
        }
        foreach ($list1 as &$value) {
            if (isset($list2key[$value[$mergekey1]]) && !empty($list2key[$value[$mergekey1]])) {
                $value = array_merge($value, $list2key[$value[$mergekey1]]);
            }
            array_push($mergeArray, $value);
        }
        return $mergeArray;
    }

    public static function sendurl($url, $access_token = '', $data, $method = 'get')
    {
        //$data = str_replace("\'","'",$data);
        if (strtolower($method) == 'post') {
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url . $access_token);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        } else {
            $curl = curl_init($url . $access_token);
        }
        //$curl = curl_init($url.$access_token);
        curl_setopt($curl, CURLOPT_FAILONERROR, 1);
        //设置允许页面重定向
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        //设置返回值赋给变量
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        //设置操作时间
        curl_setopt($curl, CURLOPT_TIMEOUT, 5);
        if ($method == 'post') {
            if (!$data) $data = '';
            //			使用post 请
            curl_setopt($curl, CURLOPT_POST, 1);
            //			设置请求参数
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }

        //开始事务
        $r = curl_exec($curl);
        curl_close($curl);
        return $r;
    }

    public static function aliyunExpressApi($expressNo, $expressType)
    {
        $host = SecretKeys::expressUrl;
        $path = SecretKeys::expressPath;
        $method = "GET";
        $appcode = SecretKeys::expressAppCode;
        $headers = array();
        array_push($headers, "Authorization:APPCODE " . $appcode);
        $querys = self::format("no={0}&type={1}", $expressNo, $expressType);
        $bodys = "";
        $url = $host . $path . "?" . $querys;
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, false);
        if (ApiConst::one == strpos("$" . $host, "https://")) {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        $res = curl_exec($curl);
        return json_decode($res, true);
    }

    /**
     * 价格格式化
     *
     * @param int $price
     * @return string    $price_format
     */
    public static function priceFormat($price)
    {
        $price_format = number_format($price, 2, '.', '');
        return $price_format;
    }


    /**
     * 获取当前访问用户地址
     * @return string
     */
    public static function getIP()
    {
        static $realip;
        if (isset($_SERVER)) {
            if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
                $realip = $_SERVER["HTTP_X_FORWARDED_FOR"];
            } else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
                $realip = $_SERVER["HTTP_CLIENT_IP"];
            } else {
                $realip = $_SERVER["REMOTE_ADDR"];
            }
        } else {
            if (getenv("HTTP_X_FORWARDED_FOR")) {
                $realip = getenv("HTTP_X_FORWARDED_FOR");
            } else if (getenv("HTTP_CLIENT_IP")) {
                $realip = getenv("HTTP_CLIENT_IP");
            } else {
                $realip = getenv("REMOTE_ADDR");
            }
        }
        return $realip;
    }

    /**
     * 获取用户所在地区
     * @param $ip
     * @return array|bool
     */
    public static function getIpCity($ip)
    {
        $url = (self::is_https()?'https':'http')."://ip.taobao.com/service/getIpInfo.php?ip=" . $ip;
        $ip = json_decode(file_get_contents($url));
        if ((string)$ip->code == '1') {
            return false;
        }
        $data = (array)$ip->data;
        return $data;
    }


    public static function getAddressByLatLng($lat,$lng){
        $key = \Our\SecretKeys::amapKey;
        $url = (self::is_https()?'https':'http').'://restapi.amap.com/v3/geocode/regeo?key='.$key.'&location='.$lng.','.$lat.'&poitype=&radius=10&extensions=all&batch=false&roadlevel=0';
        $address = json_decode(file_get_contents($url));
        if($address->status){
            return json_decode(json_encode($address->regeocode->addressComponent),true);
        }
        return false;
    }

    public static function getCityCodeByLatLng($lat,$lng){
        $address = self::getAddressByLatLng($lat,$lng);
        if($address&&isset($address['citycode'])){
            return $address['citycode'];
        }
        return false;
    }

}
