<?php
namespace app\admin\controller;
use think\Controller;
use think\Db;
/**
 * 后台插件列表控制器
 */
class Plugin extends Home{
     /* 插件列表查询首页 */
	public function index(){     
      
		$this->meta_title="插件列表管理";
		$this->assign('meta_title', $this->meta_title);		  
        $plugin_dir =PLUGIN_PATH;
        $dirs = array_map('basename',glob($plugin_dir.'*', GLOB_ONLYDIR));
        if($dirs === FALSE || !file_exists($plugin_dir)){
            $this->error( '插件目录不可读或者不存在');
        }
		$plugins			=	array();
		$where[]=['name','in',$dirs];
		$list=db('Plugin')->where($where)->field(true)->select();
		foreach($list as $plugin){
			$plugin['uninstall']		=	0;
			$plugins[$plugin['name']]	=	$plugin;
		}
        foreach ($dirs as $value) {
            if(!isset($plugins[$value])){
				$class = get_plugin_class($value);
				
				if(!class_exists($class)){ // 实例化插件失败忽略执行
					$this->error('插件'.$value.'的入口文件不存在！');
					continue;
				}
                $obj    =   new $class;
				$plugins[$value]	= $obj->info;
				if($plugins[$value]){
					$plugins[$value]['uninstall'] = 1;
                    unset($plugins[$value]['status']);
				}
			}
        }
       $list=  $this->getlist($plugins,'uninstall','desc');
	   $count=count($list);
       $Page=new \app\common\model\Page($count,10);
       $res["page"]=$Page->render();
       $p=input('p')?input('p'):1;
       array_multisort(array_column($list,'uninstall'),SORT_DESC,$list);
	   $res["list"]=array_chunk($list,10)[$p-1];
       $this->assign('res',$res);// 赋值数据集
	   return $this->fetch("plugin/index"); 
	}

   public function getlist($list,$field, $sortby='asc') {
      if(is_array($list)){
       $sort = $resultSet = array();
       foreach ($list as $i => $data)
           $sort[$i] = &$data[$field];
       switch ($sortby) {
           case 'asc': 
                asort($sort);
                break;
           case 'desc':
                arsort($sort);
                break;
           case 'nat': 
                natcasesort($sort);
                break;
       }
       foreach ( $sort as $key=> $val)
           $resultSet[] = &$list[$key];
       return $resultSet;
   }
   return false;
}
	
 
 
  /**
     * 启用插件
     */
    public function enable(){
        $id             =   safe_replace(input('id'));
       
		$data['status']=1;
		$map['id'] = $id;
        $res = db('plugin')->where($map)->update($data);
        if($res){
			cache('hooks', null); 
            $this->success('禁用成功');
        }else{
            $this->error('禁用失败');
        }
    }
 
	 /**
     * 安装插件
     */
    public function install(){
        $plugin_name     =   trim(input('plugin_name'));
        $class          =   get_plugin_class($plugin_name);
        if(!class_exists($class)){
		       $this->error('插件不存在');
		}
        $plugins  =   new $class;
        $info = $plugins->info;
        if(!$info || !$plugins->checkInfo())//检测信息的正确性
		{  
		     $this->error('插件信息缺失');
		}
        
        $install_flag   =   $plugins->install();
        if(!$install_flag){
            $this->error('缺少安装函数');
        }
        $pluginsModel    =  db('plugin');
        $data           =  $info;
        $res=db('plugin')->insert($data);
        if($res){
                 cache('hooks', null);
                $this->success('安装成功','index');
        }else{
                $this->error('安装插件');
          }
    }

    /**
     * 卸载插件
     */
    public function uninstall(){
      
        $id             =   safe_replace(input('id'));
		$map['id'] = $id;
        $info     =   db('plugin')->where($map)->find(); 
		if(!$info){
		   $this->error('插件不存在');
		}
        $class          =   get_plugin_class($info['name']);
      
        if( !class_exists($class)){
		   $this->error('插件不存在');
		}
        session('plugins_uninstall_error',null);
        $plugins =   new $class;
        $uninstall=  $plugins->uninstall();
        if(!$uninstall){
		    $this->error('执行插件预卸载操作失败');
		}
		$map2['addons']=$info['name'];
		if(db("hooks")->where($map2)->select()){
          //if(!db("hooks")->where($map2)->delete()){
            //$this->error('卸载插件所挂载的钩子数据失败');
           //}
		}
		$map['id'] = $id;
        $res = db('plugin')->where($map)->delete();
        if($res){ 
		    cache('hooks', null);
            $this->success('卸载成功','index');
        }else{
            $this->error('卸载失败');
        }
    }
	

    /**
     * 禁用插件
     */
    public function disable(){
        $id             =   safe_replace(input('id'));
       
		$data['status']=0;
		$map['id'] = $id;
        $res = db('plugin')->where($map)->update($data);
        if($res){
			cache('hooks', null); 
            $this->success('禁用成功','index');
        }else{
            $this->error('禁用失败');
        }
        
    }
   
	 /* 增加插件 */
	public function add($id=""){  
	   if($_POST){
		   
		   $data=array();
		  	foreach ($_POST as $k=>$v){
				
			      $data[$k]=safe_replace($v);
				
			} 
			$data['admin']=0; 
			if(isset($_POST['admin'])&&$_POST['admin']==1){
				 $data['admin']=1; 
			 }
			 $data['index']=0; 
			if(isset($_POST['index'])&&$_POST['index']==1){
				 $data['index']=1; 
			 }
			 
			$data['status']=0; 
			if(isset($_POST['status'])&&$_POST['status']==1){
				 $data['status']=1; 
			 } 
          $data['name']   =  strtolower(safe_replace($data['name']));
		  if(!$data['name']){
		    $this->error('插件标识必须');
		  }
        //检测插件名是否合法
        $plugins_dir             =  PLUGIN_PATH;
        if(file_exists("{$plugins_dir}{$data['name']}")){
            $this->error('插件已经存在了');
        }
		$class=ucfirst($data['name']);
			
		 $hook = '';
		if(input('hook')){ 
		 $hookarray=explode("_",input('hook'));	
        foreach ($hookarray as $value) {
			
			
			$hoo['name']=$value;
			if(db("hooks")->where($hoo)->select()){
				 $this->error('钩子'.$value.'已经存在了');		  
			}
			else{$hoo['addons']=$data['name'];
			$hoo['description']=$data['title'].'的钩子';
				 db("hooks")->insert($hoo);	
			}
			
			
            $hook .= <<<str
        //实现的{$value}钩子方法
        public function {$value}(\$param=[]){
           
        }

str;
        }
		}
        $str = <<<str
<?php
namespace plugin\\{$data['name']};
use app\index\behavior\Plugin;
use think\Db;
/**
 * {$data['title']}插件
 * @author {$data['author']}
 */
    class {$class} extends Plugin{

        public \$info = array(
            'name'=>'{$data['name']}',
            'title'=>'{$data['title']}',
            'description'=>'{$data['description']}',
            'status'=>{$data['status']},
            'author'=>'{$data['author']}',
            'version'=>'{$data['version']}',
		    'admin'=>'{$data['admin']}',
			'index'=>'{$data['index']}',
			'ids'=>'{$data['ids']}'
        );

        public function install(){
            return true;
        }

        public function uninstall(){
            return true;
        }

{$hook}
    }
str;
		
        
        $plugins_dir             = PLUGIN_PATH;
        //创建目录结构
        $files          =   array();
        $plugin_dir      =   "$plugins_dir{$data['name']}/";
        $files[]        =   $plugin_dir;
        $plugin_name     =   "{$class}.php";
        $files[]        =   "{$plugin_dir}{$plugin_name}";
        if(isset($data['has_config'])&&$data['has_config'] == 1);//如果有配置文件
		{   $files[]    =   $plugin_dir.'config.php';
		
		}
            $files[]    =   "{$plugin_dir}controller/";         
			$files[]    =   "{$plugin_dir}model/";		
		    $files[]    =   "{$plugin_dir}".ucfirst($data['name']).".php";
			$files[]    =   "{$plugin_dir}view/";
			if($data['admin']){
			  $files[]    =   "{$plugin_dir}view/lists/";
			}
			if($data['index']){
			   $files[]    =   "{$plugin_dir}view/index/";
			}
			$files[]    =   "{$plugin_dir}config/";
			$files[]    =   "{$plugin_dir}validate/";
			$files[]    =   "{$plugin_dir}view/static/";
			$files[]    =   "{$plugin_dir}view/static/images/";
			$files[]    =   "{$plugin_dir}view/static/css/";
			$files[]    =   "{$plugin_dir}view/static/js/";
            $files[]    =   "{$plugin_dir}view/static/css/style.css";
		
     
      foreach ($files as $key => $value) {
            if(substr($value, -1) == '/'){
               mkdir($value);
           }else{
               @file_put_contents($value, '');
	      }
	  }
      file_put_contents("{$plugin_dir}{$plugin_name}", $str); 
     
	  
	  $ROOT_PATH= str_replace("application","",env('app_path')); 
	  $name=$data['name'];
	  $file = file_get_contents($ROOT_PATH . 'install\conf\Base.conf');
	  $file = str_replace('[SPACE]', strtolower($name), $file); 	
	  file_put_contents($ROOT_PATH . 'plugin\\'.strtolower($name).'\controller\Base.php', $file);
	  $file = file_get_contents($ROOT_PATH . 'install\conf\admin.conf');
	  $file = str_replace('[SPACE]', strtolower($name), $file); 	
	  file_put_contents($ROOT_PATH . 'plugin\\'.strtolower($name).'\controller\Admin.php', $file);
	  $file = file_get_contents($ROOT_PATH . 'install\conf\common.conf');
	  $file = str_replace('[SPACE]', strtolower($name), $file); 	
	  file_put_contents($ROOT_PATH . 'plugin\\'.strtolower($name).'\common.php', $file);
	  if($data['admin']){	
	    $file = file_get_contents($ROOT_PATH . 'install\conf\lists.conf');
	    $file = str_replace('[SPACE]', strtolower($name), $file); 	
	    file_put_contents($ROOT_PATH . 'plugin\\'.strtolower($name).'\controller\Lists.php', $file);
		$index="{$plugin_dir}view/lists/index.html";	  
        $indexhtml= file_get_contents(ROOT_PATH . 'install\conf\plugin.conf');
	    file_put_contents($index, $indexhtml); 
	  }
	   if($data['index']){
	    $file = file_get_contents($ROOT_PATH . 'install\conf\index_index.conf');
	    $file = str_replace('[SPACE]', strtolower($name), $file); 	
	    file_put_contents($ROOT_PATH . 'plugin\\'.strtolower($name).'\controller\Index.php', $file);
		$index="{$plugin_dir}view/index/index.html";	  
        $indexhtml= file_get_contents(ROOT_PATH . 'install\conf\plugin.conf');
	    file_put_contents($index, $indexhtml); 
	   }
	  $file = file_get_contents($ROOT_PATH . 'install\conf\session.conf');
	  $file = str_replace('[SPACE]', strtolower($name), $file); 	
	  file_put_contents($ROOT_PATH . 'plugin\\'.strtolower($name).'\config\session.php', $file);
	  
	  $file = file_get_contents($ROOT_PATH . 'install\conf\cookie.conf');
	  $file = str_replace('[SPACE]', strtolower($name), $file); 	
	  file_put_contents($ROOT_PATH . 'plugin\\'.strtolower($name).'\config\cookie.php', $file);
      if(isset($data['has_config'])&&$data['has_config'] == 1){ 
   	      $conf= file_get_contents(ROOT_PATH . 'install\conf\config.conf');
		  file_put_contents("{$plugin_dir}config.php",$conf);
	   }
	      if($data){
			  addUserLog("add_plugin",session_uid());
		      $this->success("创建成功！",cookie("__forward__"));
		  }else{
			  $error=$Plugin->getError()?$Plugin->getError():"新增失败！";
			  $this->error($error);
		  } 
       }


	  else{
		
       
		  $this->meta_title="创建插件";
		    cookie("__forward__",input('server.HTTP_REFERER'));
		  $this->assign('meta_title', $this->meta_title);
	      return $this->fetch("plugin/add");
	  }
	}
    
	public function update(){
		if($_POST){
			 
			 if(isset($_POST['admin'])&&$_POST['admin']==1){
				 $admin=1; 
			 }
			 $data = array(
            'name'=>input('name'),
            'title'=>input('title'),
            'description'=>input('description'),
            'author'=>input('author'),
            'version'=>input('version'),		
			'admin'=> isset($admin)?$admin:0,
			'ids'=>input('ids'),
              );	 
			  
            $res=db('plugin')->where("name",input('name'))->update($data);
            if($res){
               $this->success('保存成功', Cookie('__forward__'));
            }else{
                $this->error('保存失败');
           }	

		}else{
		
        $id   =  safe_replace(input('id'));
        $info  =  db('plugin')->where("id",$id)->find();
        if(!$info){
		    $this->error('插件未安装');
		} 
		$this->assign('info',$info);
		 $this->meta_title="插件配置";
		 cookie("__forward__",input('server.HTTP_REFERER'));
		 $this->assign('meta_title', $this->meta_title);
       
        return $this->fetch();
		}
	}
    public function edit(){
		if($_POST){
			$Plugin = new \app\admin\model\Plugin;
            $res=$Plugin->validate(true)->allowField(true)->save($_POST,['id' => $_POST['id']]);
            if($res){
               $this->success('保存成功', Cookie('__forward__'));
            }else{
                $this->error('保存失败');
           }	

		}else{
		
        $id   =  safe_replace(input('id'));
        $info  =  db('plugin')->where("id",$id)->find();
        if(!$info){
		    $this->error('插件未安装');
		}
        $class = get_plugin_class($info['name']);
        if(!class_exists($class)){
		     $this->error("插件{$info['name']}无法实例化");		
		}
        $data  =   new $class;
        $info['plugin_path'] = $data->plugin_path;
        $this->meta_title   =   '设置插件-'.$data->info['title'];
        $config =  $info['config'];
		 $this->assign('info',$info);
		unset( $info);
        $info['config'] = include $data->config_file; 
		
        if($config){
            $config = json_decode($config, true);
            foreach ( $info['config'] as $key => $value) {
				
                if(isset($value['type'])&&$value['type'] !=='group'){
                    $info['config'][$key]['value'] = $config[$key];
                }else{
                    foreach ($value['options'] as $gourp => $v) {
                        foreach ($v['options'] as $k => $value) {
                             $info['config'][$key]['options'][$gourp]['options'][$k]['value'] = $config[$k];
                        }
                    }
                }
            }
        }
         $this->assign('data',$info);//dump($info['config']);
		
		  $this->meta_title   =   '设置插件-'.$data->info['title'];
		 cookie("__forward__",input('server.HTTP_REFERER'));
		 $this->assign('meta_title', $this->meta_title);
       
        return $this->fetch();
	   }
    }

}
