You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
902 lines
24 KiB
902 lines
24 KiB
<?php
|
|
|
|
if (!function_exists('matchLatLng')) {
|
|
function matchLatLng($latlng)
|
|
{
|
|
$match = "/^\d{1,3}\.\d{1,30}$/";
|
|
return preg_match($match, $latlng) ? $latlng : 0;
|
|
}
|
|
}
|
|
|
|
|
|
if (!function_exists('getDistanceBuilder')) {
|
|
function getDistanceBuilder($lat, $lng)
|
|
{
|
|
return "ROUND(6378.138 * 2 * ASIN(SQRT(POW(SIN((" . matchLatLng($lat) . " * PI() / 180 - latitude * PI() / 180) / 2), 2) + COS(" . matchLatLng($lat) . " * PI() / 180) * COS(latitude * PI() / 180) * POW(SIN((" . matchLatLng($lng) . " * PI() / 180 - longitude * PI() / 180) / 2), 2))) * 1000) AS distance";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!function_exists('error_stop')) {
|
|
function error_stop($msg = '', $code = 0, $data = null, $status_code = 200, $header = [])
|
|
{
|
|
$result = [
|
|
'code' => $code ?: 0,
|
|
'msg' => $msg,
|
|
'data' => $data
|
|
];
|
|
|
|
$response = \think\Response::create($result, 'json', $status_code)->header($header);
|
|
throw new \think\exception\HttpResponseException($response);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
* 过滤掉字符串中的 sql 关键字
|
|
*/
|
|
if (!function_exists('filter_sql')) {
|
|
function filter_sql($str)
|
|
{
|
|
$str = strtolower($str); // 转小写
|
|
$str = str_replace("and", "", $str);
|
|
$str = str_replace("execute", "", $str);
|
|
$str = str_replace("update", "", $str);
|
|
$str = str_replace("count", "", $str);
|
|
$str = str_replace("chr", "", $str);
|
|
$str = str_replace("mid", "", $str);
|
|
$str = str_replace("master", "", $str);
|
|
$str = str_replace("truncate", "", $str);
|
|
$str = str_replace("char", "", $str);
|
|
$str = str_replace("declare", "", $str);
|
|
$str = str_replace("select", "", $str);
|
|
$str = str_replace("create", "", $str);
|
|
$str = str_replace("delete", "", $str);
|
|
$str = str_replace("insert", "", $str);
|
|
$str = str_replace("union", "", $str);
|
|
$str = str_replace("alter", "", $str);
|
|
$str = str_replace("into", "", $str);
|
|
$str = str_replace("'", "", $str);
|
|
$str = str_replace("or", "", $str);
|
|
$str = str_replace("=", "", $str);
|
|
|
|
return $str;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* 检测字符串是否是版本号
|
|
*/
|
|
if (!function_exists('is_version_str')) {
|
|
/**
|
|
* 检测字符串是否是版本号
|
|
* @param string $version
|
|
* @return boolean
|
|
*/
|
|
function is_version_str($version)
|
|
{
|
|
$match = "/^([0-9]\d|[0-9])(\.([0-9]\d|\d))+/";
|
|
return preg_match($match, $version) ? true : false;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 删除目录
|
|
*/
|
|
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) {
|
|
if ($fileinfo->isDir() === 'rmdir') rmdir(($fileinfo->getRealPath()));
|
|
if ($fileinfo->isDir() === 'unlink') unlink(($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 . DIRECTORY_SEPARATOR . $iterator->getSubPathName();
|
|
if (!is_dir($sontDir)) {
|
|
@mkdir($sontDir, 0755, true);
|
|
}
|
|
} else {
|
|
copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (!function_exists('is_url')) {
|
|
function is_url($url)
|
|
{
|
|
if (preg_match("/^(http:\/\/|https:\/\/)/", $url)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
* 快捷设置跨域请求头(跨域中间件失效时,一些特殊拦截时候需要用到)
|
|
*/
|
|
if (!function_exists('set_cors')) {
|
|
/**
|
|
* 快捷设置跨域请求头(跨域中间件失效时,一些特殊拦截时候需要用到)
|
|
*
|
|
* @return void
|
|
*/
|
|
function set_cors()
|
|
{
|
|
$header = [
|
|
'Access-Control-Allow-Origin' => '*', // 规避跨域
|
|
'Access-Control-Allow-Credentials' => 'true',
|
|
'Access-Control-Max-Age' => 1800,
|
|
'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
|
|
'Access-Control-Allow-Headers' => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With, platform',
|
|
];
|
|
// 直接将 header 添加到响应里面
|
|
foreach ($header as $name => $val) {
|
|
header($name . (!is_null($val) ? ':' . $val : ''));
|
|
}
|
|
|
|
if (request()->isOptions()) {
|
|
// 如果是预检直接返回响应,后续都不在执行
|
|
exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (!function_exists('sheep_config')) {
|
|
/**
|
|
* 获取SheepAdmin配置
|
|
* @param string $code 配置名
|
|
* @return string
|
|
*/
|
|
function sheep_config(string $code, $cache = true)
|
|
{
|
|
return \app\admin\model\shopro\Config::getConfigs($code, $cache);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 获取前端用户
|
|
*/
|
|
if (!function_exists('auth_user')) {
|
|
function auth_user($throwException = false)
|
|
{
|
|
if (\app\common\library\Auth::instance()->isLogin()) {
|
|
return \app\common\library\Auth::instance()->getUser();
|
|
}
|
|
if ($throwException) {
|
|
error_stop('请登录后操作', 0, null, 401);
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 获取管理员信息
|
|
*/
|
|
if (!function_exists('auth_admin')) {
|
|
function auth_admin()
|
|
{
|
|
if (\app\admin\library\Auth::instance()->isLogin()) {
|
|
$admin = \app\admin\library\Auth::instance()->getUserInfo(); // 这里获取的是个数组,转为模型
|
|
if ($admin) {
|
|
return \app\admin\model\shopro\Admin::where('id', $admin['id'])->find();
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!function_exists('has_redis')) {
|
|
|
|
/**
|
|
* 判断是否配置好了 redis
|
|
*
|
|
* @param boolean $is_exception 是否 抛出异常
|
|
* @return boolean
|
|
*/
|
|
function has_redis($is_exception = false, $cache = true)
|
|
{
|
|
$key = 'has_redis';
|
|
if ($cache && cache('?' . $key)) {
|
|
// 使用缓存,并且存在缓存
|
|
return cache($key);
|
|
}
|
|
|
|
$error_msg = '';
|
|
try {
|
|
addons\shopro\facade\Redis::ping();
|
|
} catch (\BadFunctionCallException $e) {
|
|
// 缺少扩展
|
|
$error_msg = $e->getMessage() ? $e->getMessage() : "缺少 redis 扩展";
|
|
} catch (\RedisException $e) {
|
|
// 连接拒绝
|
|
\think\Log::write('redis connection redisException fail: ' . $e->getMessage());
|
|
$error_msg = $e->getMessage() ? $e->getMessage() : "redis 连接失败";
|
|
} catch (\Exception $e) {
|
|
// 异常
|
|
\think\Log::write('redis connection fail: ' . $e->getMessage());
|
|
$error_msg = $e->getMessage() ? $e->getMessage() : "redis 连接异常";
|
|
}
|
|
|
|
cache($key, ($error_msg ? false : true), 10); // 保存缓存
|
|
if ($error_msg) {
|
|
if ($is_exception) {
|
|
throw new \Exception($error_msg);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
if (!function_exists('redis_cache')) {
|
|
/**
|
|
* 缓存管理
|
|
* @param mixed $name 缓存名称,如果为数组表示进行缓存设置
|
|
* @param mixed $value 缓存值
|
|
* @param mixed $options 缓存参数
|
|
* @param string $tag 缓存标签
|
|
* @return mixed
|
|
*/
|
|
function redis_cache($name = null, $value = '', $ttl = null)
|
|
{
|
|
$cache = new \addons\shopro\library\RedisCache;
|
|
|
|
if ($name === null) {
|
|
return $cache;
|
|
} elseif ('' === $value) {
|
|
// 获取缓存
|
|
return 0 === strpos($name, '?') ? $cache->has(substr($name, 1)) : $cache->get($name);
|
|
} elseif (is_null($value)) {
|
|
// 删除缓存
|
|
return $cache->delete($name);
|
|
} else {
|
|
// 缓存数据
|
|
return $cache->set($name, $value, $ttl);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 检测系统必要环境
|
|
*/
|
|
if (!function_exists('check_env')) {
|
|
function check_env($need = [], $is_throw = true)
|
|
{
|
|
$need = is_string($need) ? [$need] : $need;
|
|
|
|
// 检测是否安装浮点数运算扩展
|
|
if (in_array('bcmath', $need)) {
|
|
if (!extension_loaded('bcmath')) {
|
|
if ($is_throw) {
|
|
error_stop('请安装浮点数扩展 【bcmath】');
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 检测是否安装了队列
|
|
if (in_array('queue', $need)) {
|
|
if (!class_exists(\think\Queue::class)) {
|
|
if ($is_throw) {
|
|
error_stop('请安装 【topthink/think-queue:v1.1.6 队列扩展】');
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 检查是否有分销功能
|
|
if (in_array('commission', $need)) {
|
|
if (!class_exists(\addons\shopro\listener\Commission::class)) {
|
|
if ($is_throw) {
|
|
error_stop('请先升级 【shopro】');
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 检查是否安装了支付扩展包
|
|
if (in_array('yansongda', $need)) {
|
|
//读取插件的状态,epay为插件标识
|
|
$info = get_addon_info('epay');
|
|
if (!$info || !$info['state']) {
|
|
if ($is_throw) {
|
|
error_stop('请确保【微信支付宝整合插件】已安装并启用');
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (version_compare($info['version'], '1.3.0') < 0) {
|
|
if ($is_throw) {
|
|
error_stop('请安装【微信支付宝整合插件】v1.3.0 及以上版本');
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!function_exists('diff_in_time')) {
|
|
/**
|
|
* 计算两个时间相差多少天,多少小时,多少分钟
|
|
*
|
|
* @param int $first 要比较的第一个时间 Carbon 或者时间格式
|
|
* @param mixed $second 要比较的第二个时间 Carbon 或者时间格式
|
|
* @param bool $format 是否格式化为字符串
|
|
* @return string|array
|
|
*/
|
|
function diff_in_time($first, $second = null, $format = true, $simple = false)
|
|
{
|
|
$second = is_null($second) ? time() : $second;
|
|
|
|
$diff = abs($first - $second); // 取绝对值
|
|
|
|
$years = floor($diff / (86400 * 365));
|
|
$surplus = $diff % (86400 * 365);
|
|
|
|
$days = floor($surplus / 86400);
|
|
$surplus = $surplus % 86400;
|
|
|
|
$hours = floor($surplus / 3600);
|
|
$surplus = $surplus % 3600;
|
|
|
|
$minutes = floor($surplus / 60);
|
|
$surplus = $surplus % 60;
|
|
|
|
$second = $surplus;
|
|
|
|
if (!$format) {
|
|
return compact('years', 'days', 'hours', 'minutes', 'second');
|
|
}
|
|
|
|
$format_text = '';
|
|
$start = false;
|
|
if ($years) {
|
|
$start = true;
|
|
$format_text .= $years . '年';
|
|
}
|
|
if ($start || $days) {
|
|
$start = true;
|
|
$format_text .= ($days % 365) . '天';
|
|
}
|
|
|
|
if ($start || $hours) {
|
|
$start = true;
|
|
$format_text .= ($hours % 24) . '时';
|
|
}
|
|
if ($start || $minutes) {
|
|
$start = true;
|
|
$format_text .= ($minutes % 60) . '分钟';
|
|
}
|
|
if (($start || $second) && !$simple) {
|
|
$start = true;
|
|
$format_text .= ($second % 60) . '秒';
|
|
}
|
|
|
|
return $format_text;
|
|
}
|
|
}
|
|
|
|
|
|
if (!function_exists('short_var_export')) {
|
|
/**
|
|
* 使用短标签打印或返回数组结构
|
|
* @param mixed $data
|
|
* @param boolean $return 是否返回数据
|
|
* @return string
|
|
*/
|
|
function short_var_export($expression, $return = FALSE)
|
|
{
|
|
$export = var_export($expression, TRUE);
|
|
$patterns = [
|
|
"/array \(/" => '[',
|
|
"/^([ ]*)\)(,?)$/m" => '$1]$2',
|
|
"/=>[ ]?\n[ ]+\[/" => '=> [',
|
|
"/([ ]*)(\'[^\']+\') => ([\[\'])/" => '$1$2 => $3',
|
|
];
|
|
$export = preg_replace(array_keys($patterns), array_values($patterns), $export);
|
|
if ((bool)$return) return $export;
|
|
else echo $export;
|
|
}
|
|
}
|
|
|
|
|
|
if (!function_exists('get_sn')) {
|
|
/**
|
|
* 获取唯一编号
|
|
*
|
|
* @param mixed $id 唯一标识
|
|
* @param string $type 类型
|
|
* @return string
|
|
*/
|
|
function get_sn($id, $type = '')
|
|
{
|
|
$id = (string)$id;
|
|
|
|
$rand = $id < 9999 ? mt_rand(100000, 99999999) : mt_rand(100, 99999);
|
|
$sn = date('Yhis') . $rand;
|
|
|
|
$id = str_pad($id, (24 - strlen($sn)), '0', STR_PAD_BOTH);
|
|
|
|
return $type . $sn . $id;
|
|
}
|
|
}
|
|
|
|
|
|
if (!function_exists('string_hide')) {
|
|
/**
|
|
* 隐藏部分字符串
|
|
*
|
|
* @param string $string 原始字符串
|
|
* @param int $start 开始位置
|
|
* @return string
|
|
*/
|
|
function string_hide($string, $start = 2)
|
|
{
|
|
if (mb_strlen($string) > $start) {
|
|
$hide = mb_substr($string, 0, $start) . '***';
|
|
} else {
|
|
$hide = $string . '***';
|
|
}
|
|
|
|
return $hide;
|
|
}
|
|
}
|
|
|
|
|
|
if (!function_exists('account_hide')) {
|
|
/**
|
|
* 隐藏账号部分字符串
|
|
*
|
|
* @param string $string 原始字符串
|
|
* @param int $start 开始位置
|
|
* @param int $end 开始位置
|
|
* @return string
|
|
*/
|
|
function account_hide($string, $start = 2, $end = 2)
|
|
{
|
|
$hide = mb_substr($string, 0, $start) . '*****' . mb_substr($string, -$end);
|
|
return $hide;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!function_exists('gen_random_str')) {
|
|
/**
|
|
* 随机生成字符串
|
|
* @param int $length 字符串长度
|
|
* @return bool $upper 默认小写
|
|
*/
|
|
function gen_random_str($length = 10, $upper = false)
|
|
{
|
|
if ($upper) {
|
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
} else {
|
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
|
|
}
|
|
|
|
$randomString = '';
|
|
for ($i = 0; $i < $length; $i++) {
|
|
$randomString .= $characters[rand(0, strlen($characters) - 1)];
|
|
}
|
|
return $randomString;
|
|
}
|
|
}
|
|
|
|
|
|
if (!function_exists('random_mobile')) {
|
|
/**
|
|
* 随机生成字符串
|
|
* @param int $length 字符串长度
|
|
* @return bool $upper 默认小写
|
|
*/
|
|
function random_mobile()
|
|
{
|
|
$mobile = '1';
|
|
$second = [3, 5, 7, 8, 9];
|
|
return $mobile . $second[array_rand($second)] . mt_rand(100000000, 999999999);
|
|
}
|
|
}
|
|
|
|
|
|
if (!function_exists('random_email')) {
|
|
/**
|
|
* 随机生成字符串
|
|
* @param int $length 字符串长度
|
|
* @return bool $upper 默认小写
|
|
*/
|
|
function random_email($prefix = '')
|
|
{
|
|
$first = [
|
|
random_mobile(),
|
|
gen_random_str(mt_rand(6, 15), mt_rand(0, 1)),
|
|
];
|
|
|
|
$first_name = $prefix ?: $first[array_rand($first)];
|
|
|
|
$suffix = [
|
|
'@gmail.com',
|
|
'@msn.com',
|
|
'@qq.com',
|
|
'@163.com',
|
|
'@163.net',
|
|
'@126.com',
|
|
'@139.com',
|
|
'@189.cn',
|
|
'@sina.com',
|
|
];
|
|
|
|
return $first_name . $suffix[array_rand($suffix)];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!function_exists('format_log_error')) {
|
|
/**
|
|
* 格式化记录日志,重要地方使用
|
|
*
|
|
* @param object $error
|
|
* @param string $name
|
|
* @param string $message
|
|
* @return void
|
|
*/
|
|
function format_log_error($error, $name = 'QUEUE', $message = '')
|
|
{
|
|
$logInfo = [
|
|
"========== $name LOG INFO BEGIN ==========",
|
|
'[ Message ] ' . var_export('[' . $error->getCode() . ']' . $error->getMessage() . ' ' . $message, true),
|
|
'[ File ] ' . var_export($error->getFile() . ':' . $error->getLine(), true),
|
|
'[ Trace ] ' . var_export($error->getTraceAsString(), true),
|
|
"============================================= $name LOG INFO ENDED ==========",
|
|
];
|
|
|
|
$logInfo = implode(PHP_EOL, $logInfo) . PHP_EOL;
|
|
\think\Log::error($logInfo);
|
|
}
|
|
}
|
|
|
|
if (!function_exists('set_token_in_header')) {
|
|
/**
|
|
* 设置token令牌到响应的header中
|
|
*
|
|
* @param string $token
|
|
* @return void
|
|
*/
|
|
function set_token_in_header($token)
|
|
{
|
|
header("Access-Control-Expose-Headers: token");
|
|
header("token: $token");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!function_exists('morph_to')) {
|
|
/**
|
|
* 多态关联
|
|
*
|
|
* @param array|object $items
|
|
* @param array $morphs
|
|
* @param array $fields
|
|
* @return array|object
|
|
*/
|
|
function morph_to($items, $morphs, $fields)
|
|
{
|
|
if ($items instanceof \think\Paginator) {
|
|
$data = $items->items();
|
|
} else if ($items instanceof \think\Collection) {
|
|
$data = $items;
|
|
} else {
|
|
$data = collection($items);
|
|
}
|
|
|
|
$allIds = [];
|
|
foreach ($data as $item) {
|
|
$allIds[$item[$fields[0]]][] = $item[$fields[1]];
|
|
}
|
|
|
|
$morphsData = [];
|
|
foreach ($allIds as $key => $ids) {
|
|
$morphData = (new $morphs[$key])::where('id', 'in', $ids)->select();
|
|
$morphsData[$key] = array_column($morphData, null, 'id');
|
|
}
|
|
|
|
$morph_key = strstr($fields[0], '_', true);
|
|
foreach ($data as &$item) {
|
|
$item->{$morph_key} = $morphsData[$item[$fields[0]]][$item[$fields[1]]] ?? null;
|
|
}
|
|
|
|
if ($items instanceof \think\Paginator) {
|
|
$items->data = $items;
|
|
} else {
|
|
$items = $data;
|
|
}
|
|
|
|
return $items;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!function_exists('image_resize_save')) {
|
|
/**
|
|
* 图片裁剪缩放并保存
|
|
* @param string $image_url 图片地址
|
|
* @param string $save_path 保存地址
|
|
* @param string $target_w 目标宽度
|
|
* @param string $target_h 目标高度
|
|
* @return void
|
|
*/
|
|
function image_resize_save($image_url, $save_path, $target_w = 200, $target_h = 200)
|
|
{
|
|
$dst_h = 200;
|
|
$dst_w = 200;
|
|
|
|
list($src_w, $src_h) = getimagesize($image_url);
|
|
$dst_scale = $dst_h / $dst_w; // 目标图像长宽比,正方形
|
|
$src_scale = $src_h / $src_w; // 原图长宽比
|
|
|
|
if ($src_scale >= $dst_scale) { // 过高
|
|
$w = intval($src_w);
|
|
$h = intval($dst_scale * $w);
|
|
|
|
$x = 0;
|
|
$y = ($src_h - $h) / 3;
|
|
} else { // 过宽
|
|
$h = intval($src_h);
|
|
$w = intval($h / $dst_scale);
|
|
|
|
$x = ($src_w - $w) / 2;
|
|
$y = 0;
|
|
}
|
|
|
|
// 剪裁
|
|
$source = imagecreatefrompng($image_url);
|
|
$croped = imagecreatetruecolor($w, $h);
|
|
imagecopy($croped, $source, 0, 0, $x, $y, $src_w, $src_h);
|
|
|
|
if ($w > $dst_w) {
|
|
$scale = $dst_w / $w;
|
|
$target = imagecreatetruecolor($dst_w, $dst_h);
|
|
$final_w = intval($w * $scale);
|
|
$final_h = intval($h * $scale);
|
|
imagecopyresampled($target, $croped, 0, 0, 0, 0, $final_w, $final_h, $w, $h);
|
|
}
|
|
|
|
// 创建目录
|
|
$dir = dirname($save_path);
|
|
if (!is_dir($dir)) {
|
|
@mkdir($dir, 0755, true);
|
|
}
|
|
|
|
imagejpeg($target, $save_path);
|
|
imagedestroy($target);
|
|
}
|
|
}
|
|
|
|
if (!function_exists('get_addonnames')) {
|
|
|
|
/**
|
|
* 获取已安装的插件
|
|
*
|
|
* @param $type enable:已安装启用的插件,disabled:已安装禁用的插件,all:所有插件
|
|
*/
|
|
function get_addonnames($type = 'enable')
|
|
{
|
|
$key = 'shopro_fa_addons_list';
|
|
if (redis_cache('?' . $key)) {
|
|
$addons = redis_cache($key);
|
|
} else {
|
|
$addons = get_addon_list();
|
|
redis_cache($key, $addons, 60);
|
|
}
|
|
|
|
$addonList = [
|
|
'all' => [],
|
|
'enable' => [],
|
|
'disabled' => []
|
|
];
|
|
foreach ($addons as $addon_name => $info) {
|
|
$addonList['all'][] = $addon_name;
|
|
$addonList[($info['state'] == 1 ? 'enable' : 'disabled')][] = $addon_name;
|
|
}
|
|
|
|
return $addonList[$type] ?? [];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (!function_exists('client_unique')) {
|
|
/**
|
|
* 获取客户端唯一标识
|
|
*
|
|
* @return boolean
|
|
*/
|
|
function client_unique()
|
|
{
|
|
// $httpName = app('http')->getName();
|
|
$httpName = '';
|
|
$url = request()->baseUrl();
|
|
$ip = request()->ip();
|
|
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
|
|
|
|
$key = $httpName . ':' . $url . ':' . $ip . ':' . $user_agent;
|
|
|
|
return md5($key);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* 删除 sql mode 指定模式,或者直接关闭 sql mode
|
|
*/
|
|
if (!function_exists('closeStrict')) {
|
|
function closeStrict($modes = [])
|
|
{
|
|
$modes = array_filter(is_array($modes) ? $modes : [$modes]);
|
|
|
|
$result = \think\Db::query("SELECT @@session.sql_mode ");
|
|
$newModes = $oldModes = explode(',', ($result[0]['@@session.sql_mode'] ?? ''));
|
|
|
|
if ($modes) {
|
|
foreach ($modes as $mode) {
|
|
$delkey = array_search($mode, $newModes);
|
|
if ($delkey !== false) {
|
|
unset($newModes[$delkey]);
|
|
}
|
|
}
|
|
$newModes = join(',', array_values(array_filter($newModes)));
|
|
} else {
|
|
$newModes = '';
|
|
}
|
|
|
|
\think\Db::execute("set session sql_mode='" . $newModes . "'");
|
|
|
|
return $oldModes;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 重新打开被关闭的 sql mode
|
|
*/
|
|
if (!function_exists('recoverStrict')) {
|
|
function recoverStrict($modes = [], $append = false)
|
|
{
|
|
if ($append) {
|
|
$result = \think\Db::query("SELECT @@session.sql_mode ");
|
|
$oldModes = explode(',', ($result[0]['@@session.sql_mode'] ?? ''));
|
|
|
|
$modes = array_values(array_filter(array_unique(array_merge($oldModes, $modes))));
|
|
}
|
|
|
|
\think\Db::execute("set session sql_mode='" . join(',', $modes) . "'");
|
|
}
|
|
}
|
|
|
|
|
|
// **********************以下方法请忽略*********************
|
|
|
|
// 当前方法直接返回 $value, 请忽略该方法
|
|
if (!function_exists('config_show')) {
|
|
function config_show($value, $data)
|
|
{
|
|
if (class_exists(\app\common\library\ShowHow::class)) {
|
|
return \app\common\library\ShowHow::configHide($value, $data);
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
}
|
|
|
|
// 当前方法直接返回 $config, 请忽略该方法
|
|
if (!function_exists('pay_config_show')) {
|
|
function pay_config_show($config)
|
|
{
|
|
if (class_exists(\app\common\library\ShowHow::class)) {
|
|
return \app\common\library\ShowHow::payConfigHide($config);
|
|
}
|
|
|
|
return $config;
|
|
}
|
|
}
|
|
|
|
// 当前方法全部返回 true, 请忽略该方法
|
|
if (!function_exists('operate_filter')) {
|
|
function operate_filter($is_exception = true)
|
|
{
|
|
if (class_exists(\app\common\library\ShowHow::class)) {
|
|
return \app\common\library\ShowHow::operateFilter($is_exception);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// 当前方法全部返回 true, 请忽略
|
|
if (!function_exists('operate_disabled')) {
|
|
function operate_disabled($is_exception = true)
|
|
{
|
|
if (class_exists(\app\common\library\ShowHow::class)) {
|
|
return \app\common\library\ShowHow::operateDisabled($is_exception);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|