qc.ifish7.com/Application/Admin/Model/TableFieldModel.class.php

526 lines
22 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Admin\Model;
use Think\Model;
class TableFieldModel extends Model{
//自动验证
//array(验证字段,验证规则,错误提示,[验证条件,附加规则,验证时间])
protected $_validate = array(
array('table_id', 'require', '请选择数据表!'),
array('formtype', 'require', '字段类型不能为空!'),
array('field', 'require', '字段名称必须填写!'),
array('field', 'isFieldUnique', '该字段名称已经存在!', 0, 'callback', 1),
array('name', 'require', '字段别名必须填写!'),
array('field', '/^[a-z_0-9]+$/i', '字段名只支持英文或数字!', 0, 'regex', 3),
);
/**
* 验证字段名是否已经存在
* @param type $fieldName
* @return boolean false已经存在true不存在
*/
public function isFieldUnique($fieldName) {
if (empty($fieldName)) {
return true;
}
if ($this->where(array('table_id' =>I("table_id"), 'field' => $fieldName))->count()){
return false;
}
return true;
}
/**
* 根据模型ID返回表名
* @param type $table_id
* @param type $table_id
* @return string
*/
protected function getTbName($table_id, $issystem = 1) {
//表名获取
$table_name = M("table")->where(array("table_id"=>$table_id))->getField("table_name");
$table_name="cms_".$table_name;
//完整表名获取 判断主表 还是副表
$table_name = $issystem ? $table_name : $table_name . "_data";
return $table_name;
}
//增加
public function data_add(){
$data=$this->create();
//数据表id
$table_id = $data['table_id'];
$fieldtype = $data['fieldtype'];
//完整表名获取 判断主表 还是副表
$table_name = $this->getTbName($table_id, $data['issystem']);
if (!$this->table_exists($table_name)) {
$this->error = '数据表不存在!';
return false;
}
//检查字段是否存在
if ($this->field_exists($table_name, $data['field'])) {
$this->error = '该字段已经存在!';
return false;
}
//增加字段
$field = array(
'tablename' => C("DB_PREFIX") . $table_name,
'fieldname' => $data['field'],
'fieldlen' => $data['fieldlen'],
'defaultvalue' => $data['defaultvalue'],
);
if ($this->addFieldSql($fieldtype, $field)) {
//更新htmlcode
$TableModel=new \Admin\Model\TableModel();
$data['htmlcode']=$TableModel->createFieldHtmlCode($data);
$data['memberhtmlcode']=$TableModel->createMemberFieldHtmlCode($data);
//
$fieldid = $this->add($data);
if ($fieldid) {
return $fieldid;
} else {
$this->error = '字段信息入库失败!';
//回滚
$this->execute("ALTER TABLE `{$field['tablename']}` DROP `{$field['fieldname']}`");
return false;
}
} else {
$this->error = '数据库字段添加失败!';
return false;
}
}
//修改
public function data_editor(){
$data=$this->create();
if (!$data['field_id']) {
$this->error = '缺少字段id';
return false;
} else {
$field_id = $field_id ? $field_id : (int) $data['field_id'];
}
//重置htmlcode
$TableModel=new \Admin\Model\TableModel();
$data['htmlcode']=htmlspecialchars_decode($data['htmlcode']);
$data['htmlcode']=$TableModel->createFieldHtmlCode($data);
//投稿的
$data['memberhtmlcode']=htmlspecialchars_decode($data['memberhtmlcode']);
$data['memberhtmlcode']=$TableModel->createMemberFieldHtmlCode($data);
//原字段信息
$info = $this->where(array("field_id" => $field_id))->find();
if (empty($info)){
$this->error = '该字段不存在!';
return false;
}
//字段主表副表不能修改
unset($data['issystem']);
//字段类型
if (empty($data['formtype'])) {
$data['formtype'] = $info['formtype'];
}
//模型id
$table_id = $info['table_id'];
$field_type = $data['fieldtype'];
//完整表名获取 判断主表 还是副表
$tablename = $this->getTbName($table_id, $info['issystem']);
if (!$this->table_exists($tablename)) {
$this->error = '数据表不存在!';
return false;
}
if (false !== $this->save($data)) {
//如果字段名变更
if ($data['field'] && $info['field']) {
//检查字段是否存在,只有当字段名改变才检测
if ($data['field'] != $info['field'] && $this->field_exists($tablename, $data['field'])) {
$this->error = '该字段已经存在!';
//回滚
$this->where(array("field_id" => $field_id))->save($info);
return false;
}
$field = array(
'tablename' => C("DB_PREFIX") . $tablename,
'newfilename' => $data['field'],
'oldfilename' => $info['field'],
'fieldlen' => $data['fieldlen'],
'defaultvalue' => $data['defaultvalue'],
);
if (false === $this->editFieldSql($field_type, $field)) {
$this->error = '数据库字段结构更改失败!';
//回滚
$this->where(array("field_id" => $field_id))->save($info);
return false;
}
//根据table_id查询model表并更新modeltemp
$model=M("model")->where(array("table_id"=>$table_id))->select();
$ModelModel=new \Admin\Model\ModelModel();
foreach($model as $v){
$ModelModel->updateModelTemp($v["modelid"]);
}
}
} else {
$this->error = '数据库更新失败!';
return false;
}
//
//
return $data;
}
//删除字段
public function data_delete($field_id,$systemfield) {
//原字段信息
$info = $this->where(array("field_id" => $field_id))->find();
if (empty($info)) {
$this->error = '该字段不存在!';
return false;
}
//模型id
$table_id = $info['table_id'];
//完整表名获取 判断主表 还是副表
$tablename = $this->getTbName($table_id, $info['issystem']);
if (!$this->table_exists($tablename)) {
$this->error = '数据表不存在!';
return false;
}
//判断是否允许删除
if (in_array($info['field'],$systemfield)){
$this->error = '系统字段不允许被删除!';
return false;
}
if ($this->deleteFieldSql($info['field'], C("DB_PREFIX") . $tablename)) {
$this->where(array("field_id" => $field_id, "table_id" => $table_id))->delete();
//根据table_id查询model表并更新modeltemp
$model=M("model")->where(array("table_id"=>$table_id))->select();
$ModelModel=new \Admin\Model\ModelModel();
foreach($model as $v){
$ModelModel->updateModelTemp($v["modelid"]);
}
} else {
$this->error = '数据库表字段删除失败!';
return false;
}
return true;
}
/**
* 根据字段类型,删除对应的字段到相应表里面
* @param type $filename 字段名称
* @param type $tablename 完整表名
*/
protected function deleteFieldSql($filename, $tablename) {
//不带表前缀的表名
$noprefixTablename = str_replace(C("DB_PREFIX"), '', $tablename);
if (empty($tablename) || empty($filename)) {
$this->error = '表名或者字段名不能为空!';
return false;
}
if (false === $this->table_exists($noprefixTablename)) {
$this->error = '该表不存在!';
return false;
}
$sql = "ALTER TABLE `{$tablename}` DROP `{$filename}`;";
if (false === $this->execute($sql)) {
$this->error = '字段删除失败!';
return false;
}
return true;
}
/**
* 根据字段类型,增加对应的字段到相应表里面
* @param type $field_type 字段类型
* @param type $field 相关配置
* $field = array(
* 'tablename' 表名(完整表名)
* 'fieldname' 字段名
* 'maxlength' 最大长度
* 'minlength' 最小值
* 'defaultvalue' 默认值
* 'minnumber' 是否正整数 和整数 1为正整数-1是为整数
* 'decimaldigits' 小数位数
* )
*/
protected function addFieldSql($field_type, $field) {
//表名
$tablename = $field['tablename'];
//字段名
$fieldname = $field['fieldname'];
//长度
$fieldlen = $field['fieldlen'];
switch ($field_type) {
case "varchar":
if (!$fieldlen) {
$fieldlen = 255;
}
$fieldlen = min($fieldlen, 255);
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` VARCHAR( {$fieldlen} ) DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "tinyint":
if (!$fieldlen) {
$fieldlen = 3;
}
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TINYINT( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "smallint":
$minnumber = intval($minnumber);
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` SMALLINT( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "mediumint":
$minnumber = intval($minnumber);
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` INT ( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "int":
$minnumber = intval($minnumber);
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` INT ( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "mediumtext":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` MEDIUMTEXT";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "text":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TEXT";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "date":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` DATE DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "datetime":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "timestamp":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "double":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` DOUBLE NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "float":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` FLOAT( {$fieldlen} ) NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "bigint":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` BIGINT( {$fieldlen} ) NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "longtext":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` LONGTEXT";
if (false === $this->execute($sql)) {
$this->error = '数据库字段添加失败!';
return false;
}
break;
case "char":
$sql = "ALTER TABLE `{$tablename}` ADD `{$fieldname}` CHAR( {$fieldlen} ) DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
default:
return false;
break;
}
return true;
}
/**
* 执行数据库表结构更改
* @param type $field_type 字段类型
* @param type $field 相关配置
* $field = array(
* 'tablename' 表名(完整表名)
* 'newfilename' 新字段名
* 'oldfilename' 原字段名
* 'maxlength' 最大长度
* 'minlength' 最小值
* 'defaultvalue' 默认值
* 'minnumber' 是否正整数 和整数 1为正整数-1是为整数
* 'decimaldigits' 小数位数
* )
*/
protected function editFieldSql($field_type, $field) {
//表名
$tablename = $field['tablename'];
//原字段名
$oldfilename = $field['oldfilename'];
//新字段名
$newfilename = $field['newfilename'] ? $field['newfilename'] : $oldfilename;
//长度
$fieldlen = $field['fieldlen'];
if (empty($tablename) || empty($newfilename)) {
$this->error = '表名或者字段名不能为空!';
return false;
}
switch ($field_type) {
case 'varchar':
//最大值
if (!$fieldlen) {
$fieldlen = 255;
}
$fieldlen = min($fieldlen, 255);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` VARCHAR( {$fieldlen} ) DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'tinyint':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` TINYINT( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'smallint':
$minnumber = intval($minnumber);
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` SMALLINT ( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT '{$defaultvalue}' DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'mediumint':
$minnumber = intval($minnumber);
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` MEDIUMINT ( {$fieldlen} ) UNSIGNED NOT NULL DEFAULT '{$defaultvalue}' DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'int':
$minnumber = intval($minnumber);
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` INT ( {$fieldlen} ) NOT NULL DEFAULT '{$defaultvalue}' DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'mediumtext':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` MEDIUMTEXT";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'text':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` TEXT";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'date':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` DATE DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'datetime':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case 'timestamp':
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "double":
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` DOUBLE NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "float":
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` FLOAT(" . $minnumber . ") NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "bigint":
$defaultvalue = intval($defaultvalue);
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` BIGINT NOT NULL DEFAULT 0";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "longtext":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` LONGTEXT";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
case "char":
$sql = "ALTER TABLE `{$tablename}` CHANGE `{$oldfilename}` `{$newfilename}` CHAR(" . $fieldlen . ") DEFAULT ''";
if (false === $this->execute($sql)) {
$this->error = '字段结构更改失败!';
return false;
}
break;
default:
$this->error = "字段类型" . $field_type . "不存在相应信息!";
return false;
break;
}
return true;
}
}