<?php
/**
* @author 龙虾 <15108148@qq.com>
* @version 2.0 2020-07-11
* @copyright 睿谷信息 <www.rgxx.com>
*/
namespace app\admin\model;
use think\Model;
use app\admin\model\Cmsfields;
use think\Db;

class Cmsmodels extends Model
{
	// 禁止自动时间戳
	protected $autoWriteTimestamp = false;
	// 设置JSON字段
	protected $json = ['config'];
    protected $jsonAssoc = true;
    // 表名
    public function getTablenameAttr($value,$data) 
    {
    	return $this->getattrinfo($data)['tablename'];
    }
    // 模型类名,驼峰
    public function getClassnameAttr($value,$data) 
    {
    	$tablename = $this->getattrinfo($data)['tablename'];
    	return ucfirst(convertUnderline($tablename));
    }
    // 类型名称
    public function getTypenameAttr($value,$data) 
    {
    	return $this->getattrinfo($data)['typename'];
    }
    // 获取模型属性
    private function getattrinfo($data)
    {
    	switch ($data['type']) {
    		case '1':
    			$prefix = 'diy_';
    			$type = '内容模型';
    			break;
    		case '2':
    			$prefix = 'func_';
    			$type = '功能模型';
    			break;
    		case '3':
    			$prefix = 'form_';
    			$type = '表单模型';
    			break;
    		case '4':
    			$prefix = 'busi_';
    			$type = '业务模型';
    			break;
    		default:
    			$prefix = 'other_';
    			$type = '其他模型';
    			break;
    	}
    	return ['tablename' => $data['name'].'model','typename' => $type];
    }
    // 获取关联
    private function related_function($type)
    {
    	switch ($type) {
    		case '1': // 内容
    			$content = 
<<<EOF
	// 只适用于详情页调用URL
    public function getUrlAttr(\$value,\$data)
    {
    	if(!empty(\$data["link"])) return \$data["link"];
    	\$siteinfo = \$this->site()->get(\$data['site_id']);
    	\$navinfo = \$this->navlist()->get(\$data['navlist_id']);
    	if(\$siteinfo['isdefault'] == 1) {
    		\$sitealias = '/';
    	} else {
    		\$sitealias = '/'.\$siteinfo['alias'].'/';
    	}
    	\$navalias = \$navinfo['alias'] ?: ('n-'. \$navinfo['id']);
    	return \$sitealias.\$navalias.'/'.(\$data['alias']?:\$data['id']).'.html';
    }
	// 关联栏目
	public function navlist()
    {
    	return \$this->belongsTo('Navlist');
    }
	// 关联评论
	public function comment()
	{
		return \$this->hasMany('Comment');
	}
	// 关联用户
	public function user()
	{
		return \$this->belongsTo('User')->field(['password','salt'],true);
	}
	// 关联管理员
	public function admin()
	{
		return \$this->belongsTo('Admin')->field(['password','salt'],true);
	}
	// 关联模型
	public function cmsmodels()
	{
		return \$this->belongsTo('Cmsmodels');
	}
EOF;
    			break;
    		case '2': // 功能
    		case '4': // 业务
    			$content = 
<<<EOF
	// 关联管理员
	public function admin()
	{
		return \$this->belongsTo('Admin')->field(['password','salt'],true);
	}
	// 关联模型
	public function cmsmodels()
	{
		return \$this->belongsTo('Cmsmodels');
	}
EOF;
    			break;
    		case '3': // 表单
    			$content = 
<<<EOF
	// 关联用户
	public function user()
	{
		return \$this->belongsTo('User')->field(['password','salt'],true);
	}
	// 关联模型
	public function cmsmodels()
	{
		return \$this->belongsTo('Cmsmodels');
	}
EOF;
    			break;
    		case '5': // 附属表
    			$content = 
<<<EOF
	// URL
    public function getUrlAttr(\$value,\$data)
    {
        \$alias = Site::cache(config("app.home.homecache"))->getFieldById(\$data['site_id'],'alias');
    	return url("content/detail",["lang" => \$alias,"mid" => \$data["cmsmodels_id"],"id" => \$data["id"]]);
    }
	// 关联评论
	public function comment()
	{
		return \$this->hasMany('Comment');
	}
	// 关联用户
	public function user()
	{
		return \$this->belongsTo('User')->field(['password','salt'],true);
	}
	// 关联管理员
	public function admin()
	{
		return \$this->belongsTo('Admin')->field(['password','salt'],true);
	}
	// 关联模型
	public function cmsmodels()
	{
		return \$this->belongsTo('Cmsmodels');
	}
EOF;
    			break;
    		default:
    			$content = '';
    			break;
    	}
    	return $content;
    }

    // 创建类文件
    public function creatModelfile($data)
    {
    	// 表名
		$data['tablename'] = $data['name'].'model';
		// 类-驼峰
		$data['classname'] = ucfirst(convertUnderline($data['tablename']));
		// 生成类文件
		if(($Opmodel=fopen ("./app/common/model/".$data['classname'].".php","w+")) === FALSE){
			return false;
		}
		$related = $this->related_function($data['type']);
		$ModelContent =
<<<EOF
<?php
/**
* @author 龙虾 <15108148@qq.com>
* @copyright 睿谷信息 <www.rgxx.com>
* @todo 自定义模型类
*/
namespace app\common\model;
use think\Model;
use app\common\model\Site;
use think\model\concern\SoftDelete;

class {$data['classname']} extends Model
{
	use SoftDelete;
	protected \$defaultSoftDelete = 0;
	protected \$json = ['extend'];
    protected \$jsonAssoc = true;

    public function getCreateTimeAttr(\$value)
    {
        return date("Y-m-d H:i:s",intval(\$value));
    }
    public function getUpdateTimeAttr(\$value)
    {
        return date("Y-m-d H:i:s",intval(\$value));
    }
    public function getDeleteTimeAttr(\$value)
    {
        return date("Y-m-d H:i:s",intval(\$value));
    }
	// 关联站点
	public function site()
	{
		return \$this->belongsTo('Site');
	}
{$related}
}
EOF;
		if(!fwrite($Opmodel,$ModelContent)){
			return false;
		}
		return $data;
    }
    
	// 增加模型
	public function add($data)
	{
		try{
			$data = $this->creatModelfile($data);
			if(empty($data)) return ['code'=>0 ,'msg'=>lang('addfalse')];
			// 入库
			$result = $this->allowField(true)->save($data);
			if($result) {
				// 删表
				Db::execute("DROP TABLE IF EXISTS `".config('database.prefix').$data['tablename']."`;");
				// 建表
				$this->createModelTable($data);
                return ['code'=>1 ,'msg'=>lang('addtrue')];
			} else {
				return ['code'=>0 ,'msg'=>lang('addfalse')];
			}
		} catch (\Exception $e) {
			return ['code'=>0 ,'msg'=>$e->getMessage()];
		}
	}

	// 修改
	public function edit($data)
	{
		try {
			$Cmsmodel = $this->get($data['id']);
			if(!$Cmsmodel) return ['code'=>0 ,'msg'=>lang('editfalse')];
			$result = $Cmsmodel->allowField(['title','torder','attamodel_id','region','config'])->save($data);
			if($result) {
				return ['code'=>1 ,'msg'=>lang('edittrue')];
			} else {
				return ['code'=>0 ,'msg'=>lang('editfalse')];
			}
		} catch (\Exception $e) {
			return ['code'=>0 ,'msg'=>$e->getMessage()];
		}
	}

	// 删除模型同时删除字段和动态字段，并删除模型类文件和对应表
	public function del($id)
	{
		try{
			$id_arr = is_array($id) ? $id : array($id);
			foreach ($id_arr as $v) {
				$Cmsmodel = $this->get($v,['cmsfields']);
				@unlink('./app/common/model/'.$Cmsmodel->classname.'.php');
				// 删表
				Db::execute("DROP TABLE IF EXISTS `".config('database.prefix').$Cmsmodel->tablename."`;");				
				//动态字段表
				\app\common\model\Diyfields::whereTablename($Cmsmodel->tablename)->delete();
				// 清除附属表数据
				if($Cmsmodel['attamodel_id']) {
					$atta_table = $this->getFieldById($Cmsmodel['attamodel_id'],'tablename');
					if(!empty($atta_table)) {
						Db::name($atta_table)->where('id > 0')->delete();
					}
				}
				$Cmsmodel->together(['cmsfields'])->delete();
			}
			return ['code'=>1 ,'msg'=>lang('deltrue')];
		} catch (\Exception $e) {
			return ['code'=>0 ,'msg'=>$e->getMessage()];
		}
	}

	// 清除数据同时删除模型对应表，内容模型时，分类保存
	public function clear($id)
	{
		try {
			$id_arr = is_array($id) ? $id : array($id);
			foreach ($id_arr as $v) {
				$Cmsmodel = $this->get($v);
				if(strtolower(config('database.type') == 'sqlite')) {
					Db::execute("DELETE FROM `".config('database.prefix').$Cmsmodel->tablename."`;");
					Db::execute("SELECT * FROM SQLITE_SEQUENCE;");
					Db::execute("UPDATE SQLITE_SEQUENCE SET `seq` = 0 WHERE NAME='".config('database.prefix').$Cmsmodel->tablename."';");
				} else {
					Db::execute("TRUNCATE TABLE `".config('database.prefix').$Cmsmodel->tablename."`;");
				}
				// 清除动态字段数据
				\app\common\model\Diyfields::whereTablename($Cmsmodel->tablename)->delete();
				// 清除附属表数据
				if($Cmsmodel['attamodel_id']) {
					$atta_table = $this->getFieldById($Cmsmodel['attamodel_id'],'tablename');
            		Db::name($atta_table)->where('id > 0')->delete();
				}
			}
			return ['code'=>1 ,'msg'=>lang('cleartrue')];
		} catch (\Exception $e) {
			return ['code'=>0 ,'msg'=>$e->getMessage()];
		}
	}

	// 复制模型包括字段
	public function copy($data)
	{
		try {
			// 创建模型文件
			$data = $this->creatModelfile($data);
			if(empty($data)) return ['code'=>0 ,'msg'=>lang('copyfalse')];
			// 入库
			$result = $this->allowField(true)->save($data);
			if($result) {
				// 表名
				$n_table = config('database.prefix').$this->getattrinfo($data)['tablename'];
				$o_table = config('database.prefix').$this->append(['tablename'])->get($data['cmsmodels_id'])['tablename'];
				// 复制字段入库
				$n_id = $this->id;
				$fields = Cmsfields::whereCmsmodelsId($data['cmsmodels_id'])->withAttr('cmsmodels_id',function($value,$data) use($n_id){
					return $n_id;
				})->select()->hidden(['id']);
				if(!$fields->isEmpty()) {
					(new Cmsfields())->saveAll($fields->toArray(),false);
				}
				if(strtolower(config('database.type')) == 'sqlite') {
					$sql_str = Db::query('SELECT * FROM sqlite_master WHERE TYPE="table" AND NAME="'.$o_table.'"')[0]['sql'];
					$sql = str_replace($o_table,$n_table,$sql_str);
					Db::execute($sql);
				} else {
					// 复制数据表结构保存索引
					$sql = "CREATE TABLE IF NOT EXISTS `$n_table` LIKE `$o_table`;";
					Db::execute($sql);
					// 修改注释
					$sql = "ALTER TABLE `$n_table` COMMENT '自定义-$data[title]';";
					Db::execute($sql);
				}
				return ['code'=>1 ,'msg'=>lang('copytrue')];
			} else {
				return ['code'=>0 ,'msg'=>lang('copyfalse')];
			}
		} catch (\Exception $e) {
			return ['code'=>0 ,'msg'=>$e->getMessage()];
		}
	}

	// 建表
	public function createModelTable($data)
	{
		// 建表
		if(strtolower(config('database.type')) == 'sqlite') {
			$sql = "CREATE TABLE `".config('database.prefix').$data['tablename']."` (";
			$sql .= "`id` INTEGER PRIMARY KEY AUTOINCREMENT,";
			if ($data['type']==1) {
				$sql .= "`title` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`navlist_id` INT DEFAULT 0,";
				$sql .= "`link` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`alias` VARCHAR(100) DEFAULT NULL,";
				$sql .= "`author` VARCHAR(100) DEFAULT NULL,";
				$sql .= "`source` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`img` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`imgs` TEXT DEFAULT NULL,";
				$sql .= "`template` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`keys` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`desc` TEXT DEFAULT NULL,";
				$sql .= "`hits` INT DEFAULT 1,";
				$sql .= "`content` TEXT DEFAULT NULL,";
				$sql .= "`user_id` INT DEFAULT 0,";
				$sql .= "`admin_id` INT DEFAULT 0,";
				$sql .= "`istop` INT DEFAULT 0,";
				$sql .= "`target` VARCHAR(50) DEFAULT NULL,";
			}
			if ($data['type']==2) {
				$sql .= "`admin_id` INT DEFAULT 0,";
			}
			if ($data['type']==3) {
				$sql .= "`user_id` INT DEFAULT 0,";
				$sql .= "`pid` INT DEFAULT 0,";
				$sql .= "`user_ip` VARCHAR(50) DEFAULT NULL,";
				$sql .= "`reply` TEXT DEFAULT NULL,";
				$sql .= "`userview` INT DEFAULT 0,";
				$sql .= "`adminview` INT DEFAULT 0,";
			}
			if ($data['type']==5) {
				$sql .= "`template` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`hits` INT DEFAULT 1,";
				$sql .= "`user_id` INT DEFAULT 0,";
				$sql .= "`admin_id` INT DEFAULT 0,";
				$sql .= "`c_id` INT DEFAULT 0,";
			}
			$sql .= "`province` INT DEFAULT 0,";
			$sql .= "`city` INT DEFAULT 0,";
			$sql .= "`district` INT DEFAULT 0,";
			$sql .= "`site_id` INT DEFAULT 0,";
			$sql .= "`cmsmodels_id` INT DEFAULT 0,";
			$sql .= "`torder` INT DEFAULT 1,";
			$sql .= "`status` INT DEFAULT 0,";
			$sql .= "`create_time` BIGINT DEFAULT 0,";
			$sql .= "`update_time` BIGINT DEFAULT 0,";
			$sql .= "`delete_time` BIGINT DEFAULT 0";
			$sql .= ");";
		} else {
			$sql = "CREATE TABLE `".config('database.prefix').$data['tablename']."`(";
			$sql .= "`id` INT(10) NOT NULL AUTO_INCREMENT,";
			if ($data['type']==1) {
				$sql .= "`title` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`navlist_id` INT DEFAULT 0,";
				$sql .= "`link` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`alias` VARCHAR(100) DEFAULT NULL,";
				$sql .= "`author` VARCHAR(100) DEFAULT NULL,";
				$sql .= "`source` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`img` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`imgs` TEXT DEFAULT NULL,";
				$sql .= "`template` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`keys` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`desc` TEXT DEFAULT NULL,";
				$sql .= "`hits` INT DEFAULT 1,";
				$sql .= "`content` TEXT DEFAULT NULL,";
				$sql .= "`user_id` INT DEFAULT 0,";
				$sql .= "`admin_id` INT DEFAULT 0,";
				$sql .= "`istop` INT DEFAULT 0,";
				$sql .= "`target` VARCHAR(50) DEFAULT NULL,";
			}
			if ($data['type']==2) {
				$sql .= "`admin_id` INT DEFAULT 0,";
			}
			if ($data['type']==3) {
				$sql .= "`user_id` INT DEFAULT 0,";
				$sql .= "`pid` INT DEFAULT 0,";
				$sql .= "`user_ip` VARCHAR(50) DEFAULT NULL,";
				$sql .= "`reply` TEXT DEFAULT NULL,";
				$sql .= "`userview` INT DEFAULT 0,";
				$sql .= "`adminview` INT DEFAULT 0,";
			}
			if ($data['type']==5) {
				$sql .= "`template` VARCHAR(255) DEFAULT NULL,";
				$sql .= "`hits` INT DEFAULT 1,";
				$sql .= "`user_id` INT DEFAULT 0,";
				$sql .= "`admin_id` INT DEFAULT 0,";
				$sql .= "`c_id` INT DEFAULT 0,";
			}
			$sql .= "`province` INT DEFAULT 0,";
			$sql .= "`city` INT DEFAULT 0,";
			$sql .= "`district` INT DEFAULT 0,";
			$sql .= "`site_id` INT DEFAULT 0,";
			$sql .= "`cmsmodels_id` INT DEFAULT 0,";
			$sql .= "`torder` INT DEFAULT 1,";
			$sql .= "`status` INT DEFAULT 0,";
			$sql .= "`create_time` BIGINT DEFAULT 0,";
			$sql .= "`update_time` BIGINT DEFAULT 0,";
			$sql .= "`delete_time` BIGINT DEFAULT 0,";
			$sql .= "PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='自定义-".$data['title']."';";
		}
        return Db::execute($sql);
	}

	// 关联字段
	public function cmsfields()
	{
		return $this->hasMany('Cmsfields');
	}

	// 获取下拉列表树数据
	public static function getModeltree()
	{
		$data = [
		['title' => '内容模型','spread' => true,'type' => 1, 'disabled' => true]
		,['title' => '功能模型','spread' => true,'type' => 2, 'disabled' => true]
		,['title' => '表单模型','spread' => true,'type' => 3, 'disabled' => true]
		,['title' => '业务模型','spread' => true,'type' => 4, 'disabled' => true]
		,['title' => '附属表模型','spread' => true,'type' => 5, 'disabled' => true]
		];
		foreach ($data as $k => $v) {
			$data[$k]['children'] = self::whereType($v['type'])->order('torder')->select()->toArray();
		}
		return json_encode($data);
	}
}