<?php
/**
 * 人人站CMS
 * ============================================================================
 * 版权所有 2015-2030 山东康程信息科技有限公司，并保留所有权利。
 * 网站地址: http://www.rrzcms.com
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 */

use think\facade\Cache;


function sysConfig($key = '', $data = null, $isUpdate = false) {
    $param = array_values(array_filter(explode('.', $key)));
    if (!$param) return null;

    $key = strtoupper('config_' . $param[0]);//缓存键

    if ($data === null) {//取值
        $cache = cache($key);//获取缓存数据
        if (isset($param[1]) && !$isUpdate) {
            if ($cache && isset($cache[$param[1]])) {
                return $cache[$param[1]];
            }
        } elseif ($cache && !$isUpdate) {
            return $cache;
        }
        $where = ['type' => $param[0],];
        $rows = M('config')->where($where)->field('name,value')->select()->toArray();
        $config = $rows ? array_column($rows, 'value', 'name') : [];
        cache($key, $config);//设置缓存

        if (isset($param[1])) {
            return $config[$param[1]] ?? null;
        }
        return $config;
    }
    //更新
    if (!is_array($data) && count($param) > 1) {
        $_data[$param[1]] = $data;
        $data = $_data;
        unset($_data);
    }
    $config = sysConfig($param[0], null, true);

    $news = [];
    foreach ($data as $k => $v) {
        $v = trim((string)$v);
        $newArr = ['name' => $k, 'value' => $v, 'type' => $param[0],];
        if (!$config || !isset($config[$k])) {
            $news[] = $newArr;
            $config[$k] = $v;
        } elseif ($config[$k] != $v) {
            $where = ['name' => $k, 'type' => $newArr['type'],];
            M('config')->where($where)->save(['value' => $v,]);
            $config[$k] = $v;
        }
    }
    $news and M('config')->insertAll($news);
    cache($key, $config);//设置缓存
}


/**
 * 获取用户session信息
 * @param string $appName 应用名称
 * @return mixed
 */
function getAccount($appName = '') {
    $appName = $appName ?: app()->http->getName();
    $key = 'account.' . $appName;
    return session($key);
}

/**
 * 获取和设置配置参数
 * @param string|array $name 参数名
 * @param mixed $value 参数值
 * @return mixed
 */
function C($name = '', $value = null) {
    return config($name, $value);
}

/**
 * Url生成
 * @param string $url 路由地址
 * @param array $vars 变量
 * @param bool|string $suffix 生成的URL后缀
 * @param bool|string $domain 域名
 * @return string
 */
function U(string $url = '', array $vars = [], $suffix = true, $domain = false) {
    $inlet = sysConfig('admin.inlet');
    return url($url, $vars, $suffix, $domain)->build($inlet ?: 0);
}

/**
 * @param string $name 表名称
 * @param bool $isCache
 * @return \think\facade\Db
 */
function M($name = '', $isCache = true) {
    $model = think\facade\Db::name($name);
    if (!env('app_debug', false)) {
        $app = app();
        if ($isCache && $app->http->getName() == 'home') {
            $model = $model->cache();
        }
    }
    return $model;
}

/**
 * 获取输入数据 支持默认值和过滤
 * @param string $key 获取的变量名
 * @param mixed $default 默认值
 * @param string $filter 过滤方法
 * @return mixed
 */
function I(string $key = '', $default = null, $filter = '') {
    return input($key, $default, $filter);
}

/**
 * 缓存管理
 * @param string $name 缓存名称
 * @param mixed $value 缓存值
 * @return mixed
 * @throws \Psr\SimpleCache\InvalidArgumentException
 */
function F(string $name = null, $value = '') {
    if (is_null($name)) {
        return false;
    }

    $cache = Cache::store('ftemp');
    if ('' === $value) {
        // 获取缓存
        return 0 === strpos($name, '?') ? $cache->has(substr($name, 1)) : $cache->get($name);
    } elseif (is_null($value)) {
        // 删除缓存
        return $cache->delete($name);
    }

    return $cache->set($name, $value, 0);
}

/**
 * 返回数组中指定多列
 * @param array $input 需要取出数组列的多维数组
 * @param string $column_keys 要取出的列名，逗号分隔，如不传则返回所有列
 * @param string $index_key 作为返回数组的索引的列
 * @return array
 */
function array_columns($input, $column_keys = null, $index_key = null) {
    $result = [];
    $keys = isset($column_keys) ? explode(',', $column_keys) : [];
    if ($input) {
        foreach ($input as $k => $v) {
            // 指定返回列
            if ($keys) {
                $tmp = [];
                foreach ($keys as $key) {
                    $tmp[$key] = $v[$key];
                }
            } else {
                $tmp = $v;
            }
            // 指定索引列
            if (isset($index_key)) {
                $result[$v[$index_key]] = $tmp;
            } else {
                $result[] = $tmp;
            }

        }
    }
    return $result;
}


/*
 * 重新生成单个数据表缓存字段文件
 */
function schemaTable($name) {
    if (!$name) return false;
    $table = $name;
    $app = app();
    $prefix = $app->db->getConnection()->getConfig('prefix');
    if (!preg_match('/^' . $prefix . '/i', $name)) {
        $table = $prefix . $name;
    }
    //调用命令行的指令
    $console = new \think\Console($app);
    $console->call('optimize:schema', ['--table', $table]);
}

/**
 * 重新生成全部数据表缓存字段文件
 */
function schemaAllTable() {
    $app = app();
    $dbtables = $app->db->query('SHOW TABLE STATUS');
    $console = new \think\Console($app);
    foreach ($dbtables as $k => $v) {
        //调用命令行的指令
        $console->call('optimize:schema', ['--table', $v['Name']]);
    }
}

/**
 * 客户端IP
 */
function getClientIP() {
    $ip = request()->ip();
    if (preg_match('/^((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1 -9]?\d))))$/', $ip)) {
        return $ip;
    }
    return '';
}

function curl($url = '', $options = []) {
    if (is_array($url)) {
        $options = $url;
        $url = null;
    }
    $options = $options ?: [];
    $url = $url ?: $options['url'];
    $method = strtoupper($options['method'] ?? $options['type'] ?? 'GET') ?: 'GET';
    $data = $options['data'] ?? '';
    $data = is_array($data) ? http_build_query($data) : $data;

    if ($method == 'GET' && $data) {
        $url .= (strpos($url, '?') ? '&' : '?') . $data;
        $data = '';
    }
    $config = [
        CURLOPT_URL => $url,
        CURLOPT_CONNECTTIMEOUT => 15,//在发起连接前等待的时间，如果设置为0，则无限等待
        CURLOPT_TIMEOUT => $options['timeout'] ?? 10,//设置cURL允许执行的最长秒数
        CURLOPT_USERAGENT => $options['userAgent'] ?? 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0',
        CURLOPT_REFERER => $options['referer'] ?? '',
        CURLOPT_COOKIE => $options['cookie'] ?? '',//cookie
        CURLOPT_HTTPHEADER => $options['headers'] ?? [],//请求头
        CURLOPT_RETURNTRANSFER => true,// true 将curl_exec()获取的信息以字符串返回，而不是直接输出。
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_POST => $method == 'POST',//是否post 请求
        CURLOPT_POSTFIELDS => $data,//post 请求数据
        CURLOPT_SSL_VERIFYPEER => false,//https请求 不验证证书和hosts
        CURLOPT_SSL_VERIFYHOST => false,//不从证书中检查SSL加密算法是否存在
        //CURLOPT_FOLLOWLOCATION => true,//跟踪301,302
        CURLOPT_MAXREDIRS => 2,//指定最多的HTTP重定向的数量，这个选项是和CURLOPT_FOLLOWLOCATION一起使用的
        CURLOPT_AUTOREFERER => true,//TRUE 时将根据 Location: 重定向时，自动设置 header 中的Referer:信息
        CURLINFO_HEADER_OUT => true,//TRUE 时追踪句柄的请求字符串，从 PHP 5.1.3 开始可用。这个很关键，就是允许你查看请求header
    ];
    $dataType = $options['dataType'] ?? 'text';
    $beforeSend = $options['beforeSend'] ?? null;

    if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
        $config[CURLOPT_FOLLOWLOCATION] = true;//跟踪301,302
    }

    $ch = curl_init();
    $beforeSend && $beforeSend instanceof \Closure && $beforeSend($config);
    curl_setopt_array($ch, $config);
    $response = curl_exec($ch);
    curl_close($ch);
    if ($dataType == 'json') {
        $response = $response ? json_decode($response, true) : $response;
    } elseif ($dataType instanceof \Closure || function_exists($dataType)) {
        $response = $dataType($response);
    }
    return $response;
}

function get_curl($url = '', $dataType = 'text') {
    return curl($url, [
        'dataType' => $dataType,
    ]);
}

function post_curl($url = '', $data = [], $dataType = 'text') {
    return curl([
        'url' => $url,
        'type' => 'post',
        'data' => $data,
        'dataType' => $dataType,
    ]);
}


include_once __DIR__ . '/function.php';