<?php

namespace app\index\controller;

use app\common\controller\BaseController;
use think\facade\View;
use think\facade\Request;
use think\facade\Db;
use think\facade\Cache;
use think\facade\Config;
use app\common\model\Cate;
use app\common\model\Comment;
use app\common\model\Article as ArticleModel;
use app\common\model\Slider;
use app\common\model\UserZan;
use app\common\model\PushJscode;
use taoler\com\Message;
use app\common\lib\Msgres;

class Article extends BaseController
{
	protected $middleware = [ 
    	'logincheck' => ['except' 	=> ['cate','detail','download'] ],
    ];
	
	//文章分类
    public function cate()
	{
		$cate = new Cate();
		$ad = new Slider();
		$article = new ArticleModel();
		//动态参数
		$ename = Request::param('ename');
		$type = Request::param('type','all');
		$page = Request::param('page',1);

		// 分类信息
		$cateInfo = $cate->getCateInfo($ename);

		//分页url
		$url = url('cate_page',['ename'=>$ename,'type'=>$type,'page'=>$page]);
		//返回最后/前面的字符串
		$path = substr($url,0,strrpos($url,"/"));
		
        //分类列表
		$artList = $article->getCateList($ename,$type,$page);
		//	热议文章
		$artHot = $article->getArtHot(10);
        //分类图片
        $ad_cateImg = $ad->getSliderList(3);
        //分类钻展赞助
        $ad_comm = $ad->getSliderList(6);

		$assignArr = [
			'ename'=>$ename,
			'cateinfo'=> $cateInfo,
			'type'=>$type,
			'artList'=>$artList,
			'artHot'=>$artHot,
			'ad_cateImg'=>$ad_cateImg,
			'ad_comm'=>$ad_comm,
			'path'=>$path,
			'jspage'=>'jie'
		];
		View::assign($assignArr);

		$cateView = is_null($cateInfo) ? 'article/cate' : 'article/' . $cateInfo->detpl . '/cate';
		return View::fetch($cateView);
    }

	//文章详情页
    public function detail()
    {
		$id = input('id');
		$page = input('page',1);
		//输出内容
        $article = new ArticleModel();
        $artDetail = $article->getArtDetail($id);
		if(is_null($artDetail)){
			// 抛出 HTTP 异常
			throw new \think\exception\HttpException(404, '无内容');
		}
		//用户个人tag标签
		$userTags = $article->where(['user_id'=>$artDetail['user_id'],'status'=>1])->where('keywords','<>','')->column('keywords');
		//转换为字符串
		$tagStr = implode(",",$userTags);
		//转换为数组并去重
		$tagArr = array_unique(explode(",",$tagStr));
		$userTagCount = count($tagArr);

		//赞列表
		$userZanList = [];
		$userZan = UserZan::where(['article_id'=>$id,'type'=>1])->select();
		if(count($userZan)) {
			foreach($userZan as $v){
				$userZanList[] = ['userImg'=>$v->user->user_img,'name'=>$v->user->name];
			}
		}
		
	
		// 设置内容的tag内链
		$artDetail['content'] = $this->setArtTagLink($artDetail['content']);

		// 标签
		$tags = [];
		$relationArticle = [];
        $artTags = Db::name('taglist')->where('article_id',$id)->select();
		if(count($artTags)) {
			foreach($artTags as $v) {
				$tag = Db::name('tag')->find($v['tag_id']);
				if(!is_null($tag)) 
				$tags[] = ['name'=>$tag['name'],'url'=> (string) url('tag_list',['ename'=>$tag['ename']])];
			}
			//相关帖子
			$relationArticle = $article->getRelationTags($artTags[0]['tag_id'],$id,5);
		}

		$tpl = Db::name('cate')->where('id', $artDetail['cate_id'])->value('detpl');
		$download = $artDetail['upzip'] ? download($artDetail['upzip'],'file') : '';

		//浏览pv
		Db::name('article')->where('id',$id)->inc('pv')->update();
		$pv = Db::name('article')->field('pv')->where('id',$id)->value('pv');

		//上一篇下一篇
		$upDownArt = $article->getPrevNextArticle($id,$artDetail['cate_id']);
		if(empty($upDownArt['previous'][0])) {
            $previous = '前面已经没有了！';
        } else {
            $previous = '<a href="' . $upDownArt['previous'][0]['url'] . '" rel="prev">' . $upDownArt['previous'][0]['title'] . '</a>';
        }
		if(empty($upDownArt['next'][0])) {
            $next = '已经是最新的内容了!';
        } else {
            $next = '<a href="' . $upDownArt['next'][0]['url'] . '" rel="prev">' . $upDownArt['next'][0]['title'] . '</a>';
        }

		//评论
		$comments = $this->getComments($id, $page);
		//最新评论时间
		$lrDate_time = Db::name('comment')->where('article_id', $id)->max('update_time',false) ?? time();
		//	热议文章
		$artHot = $article->getArtHot(10);
        //广告
        $ad = new Slider();
        //分类图片
        $ad_artImg = $ad->getSliderList(4);
        //分类钻展赞助
        $ad_comm = $ad->getSliderList(7);
		//push
		$push_js = Db::name('push_jscode')->where(['delete_time'=>0,'type'=>1])->cache(true)->select();
		
		View::assign([
			'article'	=> $artDetail,
			'pv'		=> $pv,
			'artHot'	=> $artHot,
			'ad_art'	=> $ad_artImg,
			'ad_comm'	=> $ad_comm,
			'tags'		=> $tags,
			'relationArticle' => $relationArticle,
			'previous'	=> $previous,
			'next'		=> $next,
			'page'		=> $page,
			'comments'	=> $comments,
			'push_js'	=> $push_js,
			'cid' 		=> $id,
			'lrDate_time' => $lrDate_time,
			'userZanList' => $userZanList,
			'userTagCount'=> $userTagCount,
			'jspage'	=> 'jie',
			$download,
		]);
	
		return View::fetch('article/'.$tpl.'/detail');
    }
	
	//评论内容
	public function getComments($id, $page)
	{
		$comment = new Comment;
		return $comment->getComment($id, $page);
	}
	
	//文章评论
	public function comment()
	{
		// 检验发帖是否开放
		if(config('taoler.config.is_reply') == 0 ) return json(['code'=>-1,'msg'=>'抱歉，系统维护中，暂时禁止评论！']);

		if (Request::isAjax()){
			//获取评论
			$data = Request::only(['content','article_id','user_id']);
			$sendId = $data['user_id'];
			$art = Db::name('article')->field('id,status,is_reply,delete_time')->find($data['article_id']);

			if($art['delete_time'] != 0 || $art['status'] != 1 || $art['is_reply'] != 1){
				return json(['code'=>-1, 'msg'=>'评论不可用状态']);
			}
			if(empty($data['content'])){
				return json(['code'=>-1, 'msg'=>'评论不能为空！']);
			}
			$superAdmin = Db::name('user')->where('id',$sendId)->value('auth');
			$data['status'] = $superAdmin ? 1 : Config::get('taoler.config.commnets_check');
			$msg = $data['status'] ? '留言成功' : '留言成功，请等待审核';
				
			//用户留言存入数据库
			if (Comment::create($data)) {
				//站内信
				$article = Db::name('article')->field('id,title,user_id,cate_id')->where('id',$data['article_id'])->find();
				// 获取分类ename
				$cate_ename = Db::name('cate')->where('id',$article['cate_id'])->value('ename');
				$title = $article['title'];
				//$link = (string) url('article_detail',['id'=>$data['article_id']]);
				$link = $this->getRouteUrl($data['article_id'], $cate_ename);

				//评论中回复@user comment
				$preg = "/@([^@\s]*)\s/";
				preg_match($preg,$data['content'],$username);
				if(isset($username[1])){
					$receveId = Db::name('user')->whereOr('nickname', $username[1])->whereOr('name', $username[1])->value('id'); 
				} else {
					$receveId = $article['user_id'];
				}
				$data = ['title'=>$title,'content'=>'评论通知','link'=>$link,'user_id'=>$sendId,'type'=>2]; //type=2为评论留言
				Message::sendMsg($sendId,$receveId,$data);
				if(Config::get('taoler.config.email_notice')) hook('mailtohook',[$this->showUser(1)['email'],'评论审核通知','Hi亲爱的管理员:</br>用户'.$this->showUser($this->uid)['name'].'刚刚对 <b>'.$title.'</b> 发表了评论，请尽快处理。']);
				$res = ['code'=>0, 'msg'=>$msg];
			} else {
				$res = ['code'=>-1, 'msg'=>'留言失败'];
			}
			return json($res);
		}
	}

    /**
     * 添加帖子文章
     * @return string|\think\Response|\think\response\Json|void
     */
    public function add()
    {
        if (Request::isAjax()) {
			// 检验发帖是否开放
			if(config('taoler.config.is_post') == 0 ) return json(['code'=>-1,'msg'=>'抱歉，系统维护中，暂时禁止发帖！']);
			// 数据
            $data = Request::only(['cate_id', 'title', 'title_color', 'user_id', 'content', 'upzip', 'keywords', 'description', 'captcha']);
			$tagId = input('tagid');

			// 验证码
			if(Config::get('taoler.config.post_captcha') == 1) {				
				if(!captcha_check($data['captcha'])){
				 return json(['code'=>-1,'msg'=> '验证码失败']);
				};
			}

			// 验证器
			$validate = new \app\common\validate\Article;
            $result = $validate->scene('Artadd')->check($data);
            if (true !== $result) {
                return Msgres::error($validate->getError());
            }
			
			// 获取内容图片音视频标识
			$iva= $this->hasIva($data['content']);
			$data = array_merge($data,$iva);

			// 处理内容
			$data['content'] = $this->downUrlPicsReaplace($data['content']);
			// 把中文，转换为英文,并去空格->转为数组->去掉空数组->再转化为带,号的字符串
			$data['keywords'] = implode(',',array_filter(explode(',',trim(str_replace('，',',',$data['keywords'])))));

			// 获取分类ename
			$cate_ename = Db::name('cate')->where('id',$data['cate_id'])->value('ename');
		
            $article = new ArticleModel();

            $result = $article->add($data);
            if ($result['code'] == 1) {
				// 获取到的最新ID
				$aid = $result['data']['id'];
				//写入taglist表
				$tagArr = [];
				if(isset($tagId)) {
					$tagIdArr = explode(',',$tagId);
					foreach($tagIdArr as $tid) {
						$tagArr[] = ['article_id'=>$aid,'tag_id'=>$tid,'create_time'=>time()];
					}
				}
				Db::name('taglist')->insertAll($tagArr);
				
				// 清除文章tag缓存
                Cache::tag('tagArtDetail')->clear();
				// 发提醒邮件
				if(Config::get('taoler.config.email_notice')) hook('mailtohook',[$this->showUser(1)['email'],'发帖审核通知','Hi亲爱的管理员:</br>用户'.$this->showUser($this->uid)['name'].'刚刚发表了 <b>'.$data['title'].'</b> 新的帖子，请尽快处理。']);

				$link = $this->getRouteUrl((int)$aid, $cate_ename);
				// 推送给百度收录接口
				$this->baiduPushUrl($link);
				    
				$url = $result['data']['status'] ? $link : (string)url('index/');
				$res = Msgres::success($result['msg'], $url);
            } else {
                $res = Msgres::error('add_error');
            }
            return $res;
        }

		
		// 子模块自定义自适应add.html模板
		$cate = Db::name('cate')->field('id,detpl')->where('ename', input('cate'))->find();
		// 子模块下有add.html模板
		if(!empty($cate)) {
			$cid = $cate['id'];
		} else {
			$cate['detpl'] = '';
			$cid = '';
		}
		// 模板路径
		$appName = $this->app->http->getName();
		$viewRoot = root_path() . config('view.view_dir_name') . DIRECTORY_SEPARATOR . $appName .  DIRECTORY_SEPARATOR;
		$view = 'article' . DIRECTORY_SEPARATOR . $cate['detpl'] . DIRECTORY_SEPARATOR . 'add.html';
		$vfile = $viewRoot . $view;

		//子模块下存在add模板则调用，否则调用article/add.html
		$addTpl = is_file($vfile) ? $vfile : 'add';

		View::assign(['jspage'=>'jie','cid'=>$cid]);
		return View::fetch($addTpl);
    }

    /**
     * 编辑文章
     * @param $id
     * @return string|\think\Response|\think\response\Json|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function edit($id)
    {
		$article = ArticleModel::find($id);
		
		if(Request::isAjax()){
			$data = Request::only(['id','cate_id','title','title_color','user_id','content','upzip','keywords','description','captcha']);
			$tagId = input('tagid');	
			
			// 验证码
			if(Config::get('taoler.config.post_captcha') == 1)
			{				
				if(!captcha_check($data['captcha'])){
				 return json(['code'=>-1,'msg'=> '验证码失败']);
				};
			}
			//调用验证器
			$validate = new \app\common\validate\Article(); 
			$res = $validate->scene('Artadd')->check($data);
			
			if(true !== $res){
                return Msgres::error($validate->getError());
			} else {
				//获取内容图片音视频标识
				$iva= $this->hasIva($data['content']);
				$data = array_merge($data,$iva);

				$data['content'] = $this->downUrlPicsReaplace($data['content']);
				// 把，转换为,并去空格->转为数组->去掉空数组->再转化为带,号的字符串
				$data['keywords'] = implode(',',array_filter(explode(',',trim(str_replace('，',',',$data['keywords'])))));

				
				$result = $article->edit($data);
				if($result == 1) {
					//处理标签
					$artTags = Db::name('taglist')->where('article_id',$id)->column('tag_id','id');
					if(isset($tagId)) {
						$tagIdArr = explode(',',$tagId);
						foreach($artTags as $aid => $tid) {
							if(!in_array($tid,$tagIdArr)){
								//删除被取消的tag
								Db::name('taglist')->delete($aid);
							}
						}
						//查询保留的标签
						$artTags = Db::name('taglist')->where('article_id',$id)->column('tag_id');
						$tagArr = [];
						foreach($tagIdArr as $tid) {
							if(!in_array($tid, $artTags)){
								//新标签
								$tagArr[] = ['article_id'=>$data['id'],'tag_id'=>$tid,'create_time'=>time()];
							}
						}
						//更新新标签
						Db::name('taglist')->insertAll($tagArr);
					}
					
                    //删除原有缓存显示编辑后内容
                    Cache::delete('article_'.$id);
					$link = $this->getRouteUrl((int) $id, $article->cate->ename);
					// 推送给百度收录接口
					$this->baiduPushUrl($link);
					$editRes = Msgres::success('edit_success',$link);
				} else {
                    $editRes = Msgres::error($result);
				}
				return $editRes;
			}
		}
			
        View::assign(['article'=>$article,'jspage'=>'jie']);
		// 编辑多模板支持
		$tpl = Db::name('cate')->where('id', $article['cate_id'])->value('detpl');
		$appName = $this->app->http->getName();
		$viewRoot = root_path() . config('view.view_dir_name') . DIRECTORY_SEPARATOR . $appName .  DIRECTORY_SEPARATOR;
		$view = 'article' . DIRECTORY_SEPARATOR . $tpl . DIRECTORY_SEPARATOR . 'edit.html';
		$vfile = $viewRoot . $view;
		$editTpl = is_file($vfile) ? $vfile : 'edit';

		return View::fetch($editTpl);
    }
	
	/**
	 * 删除
	 *
	 * @return void
	 */
    public function delete()
	{
		$article = ArticleModel::find(input('id'));
		$result = $article->together(['comments'])->delete();
		if($result) {
		    $res = Msgres::success('delete_success');
		} else {
			$res = Msgres::error('delete_error');
		}
		return $res;
	}

	/**
	 * 上传接口
	 *
	 * @return void
	 */
	public function uploads()
    {
        $type = Request::param('type');
        return $this->uploadFiles($type);
    }

    /**
	 * 附件下载
	 *
	 * @param [type] $id
	 * @return void
	 */
    public function download($id)
    {
        $zipdir = Db::name('article')->where('id',$id)->value('upzip');
        $zip = substr($zipdir,1);
		Db::name('article')->cache(true)->where('id',$id)->inc('downloads')->update();
		//删除缓存显示下载后数据
        Cache::delete('article_'.$id);
        return download($zip,'my');
    }

	/**
	 * 获取描述，过滤html
	 *
	 * @return void
	 */
	public function getDescription()
	{
		$data = Request::only(['content']);
		$description = getArtContent($data['content']);
		return json(['code'=>0,'data'=>$description]);
	}

	/**
	 * 标题调用百度关键词词条
	 *
	 * @return void
	 */
	public function getWordList()
	{
		$title = input('title');
		return $this->getBdiduSearchWordList($title);
	}

    /**
	 * 关键词
	 *
	 * @return void
	 */
    public function keywords()
    {
        $data = Request::only(['flag','keywords','content']);
		return $this->setKeywords($data);
    }

	// 文章置顶、加精、评论状态
	public function jieset()
	{
		$data = Request::param();
		$article = ArticleModel::field('id,is_top,is_hot,is_reply')->find($data['id']);
		switch ($data['field']){
            case  'top':
                if($data['rank']==1){
                    $article->save(['is_top' => 1]);
                    $res = ['status'=>0,'msg'=>'置顶成功'];
                } else {
                    $article->save(['is_top' => 0]);
                    $res = ['status'=>0,'msg'=>'置顶已取消'];
                }
            break;
            case 'hot':
                if($data['rank']==1){
                    $article->save(['is_hot' => 1]);
                    $res = ['status'=>0,'msg'=>'加精成功'];
                } else {
                    $article->save(['is_hot' => 0]);
                    $res = ['status'=>0,'msg'=>'加精已取消'];
                }
            break;
            case 'reply':
                if($data['rank']==1){
                    $article->save(['is_reply' => 1]);
                    $res = ['status'=>0,'msg'=>'禁评成功'];
                } else {
                    $article->save(['is_reply' => 0]);
                    $res = ['status'=>0,'msg'=>'禁评已取消'];
                }
        }
        //删除本贴设置缓存显示编辑后内容
        Cache::delete('article_'.$data['id']);
		//清除文章tag缓存
		Cache::tag('tagArtDetail')->clear();
		return json($res);	
	}
	
	// 改变标题颜色
	public function titleColor()
	{
		$data = Request::param();
		$result = ArticleModel::update($data);
		if($result){
			//清除文章缓存
			Cache::tag(['tagArt','tagArtDetail'])->clear();
			$res = ['code'=> 0, 'msg'=>'标题颜色设置成功'];
		}else{
			$res = ['code'=> -1, 'msg'=>'标题颜色设置失败'];
		}
		return json($res);
	}
	
	/**
	 * 内容中是否有图片视频音频插入
	 *
	 * @param [type] $content
	 * @return boolean
	 */
	public function hasIva($content)
	{
		//判断是否插入图片
		$isHasImg = strpos($content,'img[');
		$data['has_img'] = is_int($isHasImg) ? 1 : 0;
		//判断是否插入视频
		$isHasVideo = strpos($content,'video(');
		$data['has_video'] = is_int($isHasVideo) ? 1 : 0;
		//判断是否插入音频
		$isHasAudio = strpos($content,'audio[');
		$data['has_audio'] = is_int($isHasAudio) ? 1 : 0;
		
		return $data;
	}

	//设置文章内容tag
	protected function setArtTagLink($content)
	{
		// tag链接数组
		$taglink = new PushJscode();
		$tag = $taglink->getAllCodes(2);
		if(count($tag)) {
			foreach($tag as $key=>$value) {
				// 匹配所有
				//$content = str_replace("$key", 'a('.$value.')['.$key.']',$content);
				// 限定匹配数量 '/'.$key.'/'

				// 匹配不包含[和]的内容
				// $pats = '/(?<!\[)'.$key.'(?!\])/';
				// $pats = '/(?<!<a\s?(.*)?)'.$key.'(?!<\/a>)/';
				//$pats = '/'.$key.'(?!<\/a>)/';

				//1.不匹配 $key</a>已经存在链接的情况
				//2.或不匹配 alt="$key等等等" $key后面有"这种情况
				$pats = '/' . $value['name'] . '\s?(?!<\/a>|\s?\S*")/is';

				preg_match($pats,$content,$arr);

				// 开启和关闭编辑器使用不同的链接方式
				$rpes = hook('taonystatus') ? '<a href="' . $value['jscode'] . '" target="_blank" title="' . $value['name'] . '" style="font-weight: bold;color:#31BDEC">' . $value['name'] . '</a>' : 'a(' . $value['jscode'] . ')[' . $value['name'] . ']';

				$content = preg_replace($pats,$rpes,$content,2);
			}
		}
		
		return $content;
	}

	//点赞文章
	public function userZanArticle()
	{
		//
		if(Request::isPost()) {
			$data = Request::post();
			$data['user_id'] = $this->uid;
			$userZan = Db::name('user_zan')->where(['user_id'=>$this->uid,'article_id'=>$data['article_id']])->find();
			if($userZan){
				return json(['code'=> -1, 'msg'=>'您已赞过了哦']);
			}
			$res = Db::name('user_zan')->insert($data);
			if($res) {
				return json(['code'=> 0, 'msg'=>'点赞成功']);
			}
		}
		
	}

	public function getCateTree()
	{
		//
		$cate = Db::name('cate')->order(['id' => 'ASC','sort' => 'ASC'])->where(['delete_time'=>0])->select()->toArray();
		
		$cateTree = array2tree($cate);

		$count = count($cateTree);
			$tree = [];			
			if($cateTree){
				$tree = ['code'=>0,'msg'=>'','count'=>$count];
				
				$res = [];	//auth_rule储存数据表中的表结构
				foreach($cateTree as $k => $v){
					//第一层子权限
					$children = [];
					if(isset($v['children'])){
						
						foreach($v['children'] as $m => $j){
							//第二层子权限
							$chichi = [];
							if(isset($j['children'])){
								//第三层子权限
								foreach($j as $s){
									if(isset($s['children'])){
										$chichi[] = ['id'=>$s['id'],'catename'=>$s['catename'],'pid'=>$s['pid']];	//子数据的子数据
									}
								}
							}
							
						//if($j['level']  < 3){}
						$children[] = ['id'=>$j['id'],'catename'=>$j['catename'],'pid'=>$j['pid'],'children'=>$chichi];		//子数据
						}
					}
					$data[] = ['id'=>$v['id'],'catename'=>$v['catename'],'pid'=>$v['pid'],'children'=>$children];
				}
				
				//构造一个顶级菜单pid=0的数组。把权限放入顶级菜单下子权限中
				//$tree['data'][] = ['id'=>0,'catename'=>'顶级','pid'=>0,'children'=>$data];
				$tree['data'] = $data;
			}
		return json($tree);
	}
	
	
}