<?php
// +----------------------------------------------------------------------
// | Wendasns [ 开源问答社区系统 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2020~2021 http://wendasns.com All rights reserved.
// +----------------------------------------------------------------------
declare (strict_types = 1);

//------------------------
// WendaSNS 助手函数
//-------------------------

use wendasns\Wend;
use wendasns\facade\Hook;
use wendasns\facade\Error;
use wendasns\facade\Image;
use app\wendasns\model\Allow;

use think\facade\View;
use think\facade\Route;
use think\facade\Config;
use think\route\Url as UrlBuild;
use think\facade\Cookie;
use app\wendasns\service\PwAsk;
use app\wendasns\service\PwArticle;
use app\wendasns\model\Links;
use app\wendasns\model\Publish;
use app\wendasns\model\AdCategory;
use app\wendasns\model\GroupPermission;

if (!function_exists('plugin_path')) {

    function plugin_path($path='')
    {
        return app()->getRootPath() . 'extend' . DIRECTORY_SEPARATOR . 'plugin' . DIRECTORY_SEPARATOR . ($path ? ltrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $path);
    }
}

if (!function_exists('href')) {

    function href(string $app = null, array $vars = [], $suffix = '')
    {
    	if(is_null($app)){
    		return '';
    	}
    	$app = str_replace('/', '_', $app);
        return (string) Route::buildUrl($app, $vars);
    }
}

if (!function_exists('hook')) {

    function hook($inlet)
    {
        return Hook::exec($inlet);
    }
}

if (!function_exists('success')) {

    function success()
    {
    	$code = 0;
    	$msg = '';
    	$data = [];
    	$option = [];
    	
    	$numargs = func_num_args();
    	if($numargs>0){
    		$vars = func_get_args();
    		if(is_numeric($vars[0])){//如果第一个参数是错误码
    			$code = $vars[0];
    			$msg = isset($vars[1]) ? $vars[1] : ($code>0?'操作失败':'操作成功');
    			$data = isset($vars[2]) ? $vars[2] : [];
    			$option = isset($vars[3]) ? $vars[3] : [];
    		}else{
    			$msg = isset($vars[0]) ? $vars[0] : '';
    			$data = isset($vars[1]) ? $vars[1] : [];
    			$option = isset($vars[2]) ? $vars[2] : [];
    		}
    	}
        Error::show($code, $msg, $data, $option);
    }
}

if (!function_exists('error')) {

    function error()
    {
    	$code = 1;
    	$msg = '';
    	$data = [];
    	
    	$numargs = func_num_args();
    	if($numargs>0){
    		$vars = func_get_args();
    		if(is_numeric($vars[0])){//如果第一个参数是错误码
    			$code = $vars[0];
    			$msg = isset($vars[1]) ? $vars[1] : ($code>0?'操作失败':'操作成功');
    			$data = isset($vars[2]) ? $vars[2] : [];
    			$option = isset($vars[3]) ? $vars[3] : [];
    		}else{
    			$msg = isset($vars[0]) ? $vars[0] : '';
    			$data = isset($vars[1]) ? $vars[1] : [];
    			$option = isset($vars[2]) ? $vars[2] : [];
    		}
    	}

        Error::show($code, $msg, $data, $option);
    }
}

if (!function_exists('configure')) {

    function configure(string $crumbs, $default = '', string $type = 'string')
    {
    	if(!Config::has("system.{$crumbs}")){
    		return $default;
    	}
    	
    	$row = Config::get("system.{$crumbs}");
    	if($type=='array'){
    		$row = unserialize($row);
    	}
        return $row;
    }
}

if (!function_exists('data_decrypt')) {

    function data_decrypt(string $string, string $key = '', int $expiry = 0)
    {
    	$key = md5($key ? $key : configure('site.pwdHash'));
    	return Wend::authcode($string, 'DECODE', $key, $expiry);
    }
}

if (!function_exists('data_encrypt')) {

    function data_encrypt(string $string, string $key = '', int $expiry = 0)
    {
    	$key = md5($key ? $key : configure('site.pwdHash'));
        return Wend::authcode($string, 'ENCODE', $key, $expiry);
    }
}

if (!function_exists('email_check')) {

    function email_check(string $email, string $code)
    {
    	if(session('?email_'.$email) && session('email_'.$email)==$code){
    		session('email_'.$email, null);
    		return true;
    	}
        return false;
    }
}

if (!function_exists('action_check')) {

    function action_check(string $permission)
    {
    	if(empty(request()->loginUser->status)){
    		error('账号待审核中...',[],['refresh'=>0]);
    	}
    	$dm = GroupPermission::where('group_id',request()->loginUser->gid)->where('type','default')->where('permission',$permission)->find();
    	if(!$dm){
    		error('所在用户组没有操作权限',[],['refresh'=>0]);
    	}
    }
}

if (!function_exists('admin_check')) {

    function admin_check(string $permission)
    {
    	if(empty(request()->loginUser->admin[$permission])){
    		return false;
    	}
    	return true;
    }
}

if (!function_exists('miniapp')) {

    function miniapp()
    {
    	$agent = $_SERVER['HTTP_USER_AGENT'];
    	if(strpos($agent, 'miniProgram') !== false){
    		if(strpos($agent, 'QQTheme') !== false){
    			return 'qq';
    		}else{
    			return 'weixin';
    		}
    	}
    	if(strpos($agent, 'baiduboxapp') !== false){
    		return 'baidu';
    	}
    	if(strpos($agent, 'ToutiaoMicroApp') !== false){
    		return 'toutiao';
    	}
        return false;
    }
}

if (!function_exists('load_article')) {

    function load_article($type='new', $limit=10, $category='all')
    {
    	$list = PwArticle::get($type, $category, 1, $limit);
        return $list;
    }
}

if (!function_exists('load_active_user')) {

    function load_active_user($limit=10)
    {
    	$list = \app\wendasns\service\PwUser::getActive($limit);
        return $list;
    }
}

if (!function_exists('load_question')) {

    function load_question($type='new', $limit=10, $category='all')
    {
    	$list = PwAsk::getAll($type, $category, 1, $limit);
        return $list;
    }
}

if (!function_exists('load_tags')) {

    function load_tags($limit=10)
    {
		$list = \app\wendasns\service\PwSrv::getTags($limit);
		return $list;
    }
}

if (!function_exists('load_comment')) {

    function load_comment($dm, $type='answer', $limit=2)
    {
    	$page = isset($_GET['page'])?$_GET['page']:1;
    	$url = (string)url('wendasns/answer/comment');
    	$row = $dm->comments()->where([
    		['mode','=',$type],
    		['status','=','normal'],
    		['remove','=',0],
    	])->order('create_time', 'desc')->paginate(['path'=>$url,'query'=>['page'=>$page,'id'=>$dm->id],'list_rows'=>$limit]);
        return $row;
    }
}

if (!function_exists('substr_format')) {

    function substr_format($str, $length = 16)
    {
    	if(mb_strlen($str, 'UTF-8') > $length){
    		$res = mb_substr($str, 0, $length, 'UTF-8');
    		return $res.'...';
    	}else{
    		return $str;
    	}
    }
}

if (!function_exists('range_time')) {

    function range_time($create_time, $format = 'Y-m-d')
    {
    	$now_time = Wend::getTime();
    	$create_time = !is_numeric($create_time)?strtotime($create_time):$create_time;
    	$cross = $now_time - $create_time;
    	switch ($cross){
    		case $cross<60:
    			$str = "{$cross}秒前";
    			break;
    		case $cross>59 && $cross<3600:
    			$cross = $cross/60;
    			$cross = floor($cross);
    			$str = "{$cross}分钟前";
    			break;
    		case $cross>3599 && $cross<86400:
    			$cross = $cross/3600;
    			$cross = floor($cross);
    			$str = "{$cross}小时前";
    			break;
    		default:
    			$cross = $cross/86400;
    			$cross = floor($cross);
    			$str = $cross > 7 ? date($format, $create_time) : "{$cross}天前";
    	}
        return $str;
    }
}

if (!function_exists('isEmpty')) {

    function isEmpty($vars)
    {
    	if($vars==''){
    		$vars = request()->filter();
    	}
        return $vars;
    }
}

if (!function_exists('template')) {

    function template($vars,$path='')
    {
    	if($vars==''){
    		return '';
    	}
    	if($path){
    		$suffix = View::getConfig('view_suffix');
    		$path = $path.$vars.'.'.$suffix;
    	}else{
    		$path = $vars;
    	}
        return View::fetch($path);
    }
}

if (!function_exists('portrait')) {

    function portrait($uid)
    {
    	$user = \app\wendasns\model\User::find($uid);
    	if(!$user){
    		return '';
    	}
    	
    	switch($user->members->auths){
    		case 1:
    			$auth = '<div class="verify"><i class="fas fa-check-circle fa-xs" style="color:#FF5722;" title="个人认证"></i></div>';
    			break;
    		case 2:
    			$auth = '<div class="verify"><i class="fas fa-check-circle fa-xs" style="color:#1E9FFF;" title="企业认证"></i></div>';
    			break;
    		case 3:
    			$auth = '<div class="verify"><i class="fas fa-check-circle fa-xs" style="color:#5FB878;" title="专家认证"></i></div>';
    			break;
    		default:
    			$auth = '';
    	}
    	
    	if($user->portrait){
    		if(substr($user->portrait,0,4)=='http'){
    			$src = $user->portrait;
    		}else{
    			list($name,$suffix) = explode('.',$user->portrait);
    			$src = (string)url('wendasns/common/portrait',['id'=>$uid],$suffix);
    		}
    		return '<div class="portrait">'.$auth.'<img src="'.$src.'"></div>';
    	}
    	
    	$word = mb_substr($user->username,0,1,'utf-8');
		$color_list = ['Gainsboro','SlateGrey','CornflowerBlue','MediumOrchid','SeaGreen','goldenrod','IndianRed','Firebrick','OrangeRed','DeepPink','red','DarkCyan','Gold'];
		$i = stripos('ABCDEFGHIJKLMNOPQRSTUVWXYZ',$word);
		if($i>12) $i = $i-13;
		$background_color = $color_list[$i];
        return '<div class="portrait">'.$auth.'<span style="background-color: '.$background_color.';"><i>'.strtoupper($word).'</i></span></div>';
    }
}


    function url(string $url = '', $vars = [], $suffix = true, $domain = true): UrlBuild
    {
    	if(!$domain){
    		$domain_bind = config('app.domain_bind');
    	}
    	$app = app('http')->getName();
    	if($app=='wendasns'){
    		app('http')->name('');
    	}

    	if(is_object($vars)){
    		$route = Route::getName();
    		$name = $vars->getName();
    		$create_time = !is_numeric($vars->create_time)?strtotime($vars->create_time):$vars->create_time;
	    	$dates = date('Y-m-d',$create_time);
	    	list($year, $month, $day) = explode('-',$dates);

	    	$r = ['id'=>$vars->id,'kid'=>$vars->kid,'category'=>$vars->categorys['dir_name'],'year'=>$year,'month'=>$month,'day'=>$day];
	    	$row = [];
	    	switch ($name){
	    		case 'Question':
	    			$dm = $route['wendasns/question/show'][0];
	    			break;
	    		case 'Article':
	    			$dm = $route['wendasns/article/show'][0];
	    			break;
	    		default:
	    			$dm = null;
	    	}
    		preg_match_all('/<(.*?)(|\?)>/',$dm['rule'],$arow);
    		foreach($arow[1] as $v){
    			if(isset($r[$v])){
    				$row[$v] = $r[$v];
    			}
    		}
    		$vars = $row;
    	}else{
    		if($url=='wendasns/topic/show'){
    			$route = Route::getName();
    			$topic = \app\wendasns\model\Topic::where('name',$vars['tags'])->find();
    			if($topic){
	    			$vars['id'] = $topic->id;
	    			$vars['py'] = $topic->alias;
	    			$dm = $route['wendasns/topic/show'][0];
		    		preg_match_all('/<(.*?)(|\?)>/',$dm['rule'],$arow);
		    		foreach($arow[1] as $v){
		    			if(isset($vars[$v])){
		    				$row[$v] = $vars[$v];
		    			}
		    		}
		    		$vars = $row;
    			}
    		}
    	}
        return Route::buildUrl($url, $vars)->suffix($suffix)->domain($domain);
    }


    function config($name = '', $value = null)
    {
        if (is_array($name)) {
            return Config::set($name, $value);
        }
        return 0 === strpos($name, '?') ? Config::has(substr($name, 1)) : Config::get($name, $value);
    }
    
if (!function_exists('getKid')) {

	function getKid($id, $dates)
	{
		$day = is_numeric($dates)?date('j',$dates):date('j',strtotime($dates));
    	$num = ['Zero','One','Two','Three','Four','Five','Six','Seven','Eight','Nine'];
    	$str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    	$day--;
		if($day<26){
			$a = $str[$day];
			if($day<10){
				$first = 0;
				$tail = $day;
			}else{
				$first = substr((string)$day,0,1) - 1;
				$tail = substr((string)$day,1,1);
			}
			$prefix = $a.strtolower(substr($num[$tail],$first,2));
		}else{
			$first = substr((string)$day,0,1) - 1;
			$tail = substr((string)$day,1,1);
			$a = $str[$tail-1];
			$prefix = $a.strtolower(substr($num[$tail],$first,2));
		}
		$random = substr(md5($id.rand()),8,8);
		$new_rand = '';
		for($x=0; $x<strlen($random); $x++){
			if(!is_numeric($random[$x])){
				$n = rand(0,1);
				$new_rand .= $n?strtoupper($random[$x]):$random[$x];
			}else{
				$new_rand .= $random[$x];
			}
		}
		return $prefix.$new_rand;
	}
}

if (!function_exists('load_links')) {

    function load_links()
    {
    	$dm = Links::where('status',1)->order('sort', 'desc')->select();
        return $dm;
    }
}

if (!function_exists('load_publish')) {

    function load_publish($limit=10)
    {
    	$dm = Publish::order('create_time', 'desc')->limit($limit)->select();
    	$a = [];
    	$b = [];
    	foreach($dm as $v){
    		if($v->istop){
    			$a[] = $v;
    		}else{
    			$b[] = $v;
    		}
    	}
    	
        return array_merge($a,$b);
    }
}

if (!function_exists('cover')) {

    function cover($dm)
    {
    	if($dm->cover){
    		$url = $dm->cover;
    	}else{
    		$name = rand(3,10);
    		$url = (string)url('wendasns/api/image',['type'=>'static','name'=>$name],'jpg',true);
    	}
    	/*preg_match('/<img.*?src="(.*?)".*?>/', $dm->content, $ar);
    	if(isset($ar[1])){
    		$url = $ar[1];
    	}else{
    		$name = rand(3,10);
    		$url = (string)url('wendasns/api/image',['type'=>'static','name'=>$name],'jpg',true);
    	}*/
    	
        return sprintf('<img alt="%s" src="%s" title="%s"/>',$dm->title,$url,$dm->title);
    }
}

if (!function_exists('load_advert')) {

    function load_advert($name,$effect=0)
    {
    	$dm = AdCategory::where('name',$name)->find();
    	if(!$dm || !$dm->status){
    		return '';
    	}
    	$advert = $dm->adverts()->where([
    		['status','=',1],
    		['create_time','<',time()],
    	])->select();
    	if($effect==1){
    		return $advert;
    	}
    	
    	$res = '';
    	$larr = [];
    	foreach($advert as $v){
    		if($v->expire_time){
    			$expire_time = strtotime($v->expire_time);
    			if($expire_time<time()){
    				continue;
    			}
    		}
    		$larr[$v->model][] = $v;
    	}
    	
    	foreach($larr as $key=>$item){
    		foreach($item as $k=>$v){
    			if($key=='img'){
    				$content = $v->url?'<a href="'.$v->url.'" target="_blank"><img src="'.$v->content.'" style="width: 100%;"/></a>':'<img src="'.$v->content.'" style="width: 100%;"/>';
    				$res .= sprintf('<div class="layui-card" style="position: relative;"><div style="position: absolute;right: 0px;bottom: 0px;"><span class="layui-badge" style="background-color: rgba(255,87,34,0.5);border-radius: 2px 0px 0px;">广告</span></div>%s</div>',$content);
    			}elseif($key=='text'){
    				$content = $v->url?'<a href="'.$v->url.'" target="_blank">'.$v->content.'</a>':$v->content;
    				$res .= sprintf('<li>%s.%s</li>',$k+1,$content);
    			}else{
    				$res .= sprintf('<div class="layui-card" style="position: relative;"><div style="position: absolute;right: 0px;bottom: 0px;"><span class="layui-badge" style="background-color: rgba(255,87,34,0.5);border-radius: 2px 0px 0px;">广告</span></div><div>%s</div></div>',$v->content);
    			}
    		}
    		if($key=='text'){
    			$res = '<div class="layui-card" style="position: relative;"><div style="position: absolute;right: 0px;bottom: 0px;"><span class="layui-badge" style="background-color: rgba(255,87,34,0.5);border-radius: 2px 0px 0px;">广告</span></div><div class="layui-card-body"><ul>'.$res.'</ul></div></div>';
    		}
    	}
        return $res;
    }
}

if (!function_exists('getSystem')) {

    function getSystem()
    {
		$current = $_SERVER ['HTTP_USER_AGENT'];
		$system = '';
		$version = '';
		if (preg_match ('/Win/i', $current )) {
	        $system = 'Win';
			if (preg_match ('/nt 10/i', $current )) {
				$version = '10';  
			} else if (preg_match ('/nt 6.3/i', $current )) {
				$version = '8.1';
			} else if (preg_match ('/nt 6.2/i', $current )) {
				$version = '8';
			} else if (preg_match ('/nt 6.1/i', $current )) {
				$version = '7';
			} else if (preg_match ('/nt 6.0/i', $current )) {
				$version = 'Vista';
			}
		}
	    else if (preg_match ('/MicroMessenger/i', $current )) {
	        $system = 'Program';//小程序
	    }
		else if (preg_match ('/Android/i', $current )) {
			$system = 'Android';
		} else if (preg_match ('/iPhone/i', $current )) {
			$system = 'iPhone';
		} else if (preg_match ('/linux/i', $current )) {
			$system = 'Linux';
		} else if (preg_match ('/unix/i', $current )) {
			$system = 'Unix';
		} else if (preg_match ('/sun/i', $current ) && preg_match ('/os/i', $current )) {
			$system = 'SunOS';
		} else if (preg_match ('/ibm/i', $current ) && preg_match ('/os/i', $current )) {
			$system = 'IBM OS/2';
		} else if (strpos ( $current, 'Macintosh' )) {
			$system = 'Mac';
		}

	    return $system.$version;
    }
}


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

        if ($pos = strpos($key, '.')) {
            // 指定参数来源
            $method = substr($key, 0, $pos);
            if (in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'route', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) {
                $key = substr($key, $pos + 1);
                if ('server' == $method && is_null($default)) {
                    $default = '';
                }
            } else {
                $method = 'param';
            }
        } else {
            // 默认为自动判断
            $method = 'param';
        }
        
        if(isset($has)){
        	return request()->has($key, $method);
        }
        
        $res = request()->$method($key, $default, $filter);
        if($res==null && !is_null($default)){
        	return $default;
        }
        return $res;
    }

    /**
     * Cookie管理
     * @param string $name   cookie名称
     * @param mixed  $value  cookie值
     * @param mixed  $option 参数
     * @return mixed
     */
    function cookie(string $name, $value = '', $option = null)
    {
    	$cookiePrefix = configure('basis.cookiePrefix');
        if (is_null($value)) {
            // 删除
            $option['expire'] = time() - 3600;
            Cookie::set($cookiePrefix.$name, '', $option);
        } elseif ('' === $value) {
            // 获取
            return 0 === strpos($name, '?') ? Cookie::has($cookiePrefix.substr($name, 1)) : Cookie::get($cookiePrefix.$name);
        } else {
            // 设置
            return Cookie::set($cookiePrefix.$name, $value, $option);
        }
    }
    
    /**
     * 生成帖子列表分类查询条件
     * @param string $name   cookie名称
     * @param mixed  $value  cookie值
     * @param mixed  $option 参数
     * @return mixed
     */
    function categoryQuery(object $dm)
    {
    	$ar = [];
    	$fun = function($dm,&$ar)use(&$fun){
	    	$ar[] = $dm->id;
	    	if(isset($dm->lowers)){
	    		foreach($dm->lowers as $v){
	    			$fun($v,$ar);
	    		}
	    	}else{
	    		return;
	    	}
    	};
    	$fun($dm,$ar);
    	return $ar;
    }

    /**
     * 生成分类导航列表
     * @param string $name   cookie名称
     * @param mixed  $value  cookie值
     * @param mixed  $option 参数
     * @return mixed
     */
    function categoryNavig(object $dm, string $type)
    {
    	$ar = [];
    	$fun = function($dm,&$ar)use(&$fun, $type){
	    	$dm->list = $dm->similar($dm->category_id,$type)->select();
	    	$ar[] = $dm->toArray();
	    	if(isset($dm->aboves)){
	    		$fun($dm->aboves,$ar);
	    	}else{
	    		return;
	    	}
    	};
    	$fun($dm,$ar);
    	sort($ar);
    	if(count($dm->lowers)>0){
    		$ar[] = ['dir_name'=>'','list'=>$dm->lowers->toArray()];
    	}
    	return $ar;
    }