Files

987 lines
29 KiB
PHP
Raw Permalink 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 Phpcmf\Model;
/**
* https://www.besyun.com
* BESCMS
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
**/
// 数据表(DDL 优先驱动;未实现时按 MySQL 源方言兼容,经 formatCreateSql 转换)
class Table extends \Phpcmf\Model {
/**
* MySQL 源方言标识符加反引号(供 formatCreateSql 转换)
*
* @param string $id
* @return string
*/
protected function _mysql_qi($id) {
return '`'.str_replace('`', '``', $this->unquote_id((string) $id)).'`';
}
/**
* 执行 MySQL 源 DDL_query_batch → dr_format_create_sql
*
* @param string $sql
* @return bool
*/
protected function _ddl_exec_mysql($sql) {
$sql = trim((string) $sql);
if ($sql === '') {
return false;
}
$rt = $this->_query_batch($sql);
if (!empty($rt['code'])) {
return true;
}
log_message('error', 'DDL compat: '.($rt['msg'] ?? $sql));
return false;
}
/**
* 修改字段(优先驱动 editField)
*
* @param string $table
* @param string $name
* @param string $type
* @param string $info
* @param string $note
* @return mixed
*/
public function edit_field($table, $name, $type, $info, $note) {
if (method_exists($this->db, 'editField')) {
return $this->db->editField($table, $name, $type, $info, $note);
}
return $this->_edit_field_compat($table, $name, $type, $info, $note);
}
/**
* @param string $table
* @param string $name
* @param string $type
* @param string $info
* @param string $note
* @return bool
*/
protected function _edit_field_compat($table, $name, $type, $info, $note) {
$table = $this->unquote_id((string) $table);
$name = $this->unquote_id((string) $name);
if ($table === '' || $name === '') {
return false;
}
$qi = $this->_mysql_qi($name);
$sql = 'ALTER TABLE '.$this->_mysql_qi($table).' CHANGE '.$qi.' '.$qi
.' '.$type.' '.$info;
$note = (string) $note;
if ($note !== '') {
$sql .= " COMMENT '".str_replace("'", "''", $note)."'";
}
return $this->_ddl_exec_mysql($sql);
}
/**
* 添加字段(优先驱动 addField)
*
* @param string $table
* @param string $name
* @param string $type
* @param string $info
* @param string $note
* @return mixed
*/
public function add_field($table, $name, $type, $info, $note) {
if (method_exists($this->db, 'addField')) {
return $this->db->addField($table, $name, $type, $info, $note);
}
return $this->_add_field_compat($table, $name, $type, $info, $note);
}
/**
* @param string $table
* @param string $name
* @param string $type
* @param string $info
* @param string $note
* @return bool
*/
protected function _add_field_compat($table, $name, $type, $info, $note) {
$table = $this->unquote_id((string) $table);
$name = $this->unquote_id((string) $name);
if ($table === '' || $name === '') {
return false;
}
$sql = 'ALTER TABLE '.$this->_mysql_qi($table).' ADD '.$this->_mysql_qi($name)
.' '.$type.' '.$info;
$note = (string) $note;
if ($note !== '') {
$sql .= " COMMENT '".str_replace("'", "''", $note)."'";
}
return $this->_ddl_exec_mysql($sql);
}
/**
* 删除字段(优先驱动 dropField)
*
* @param string $table
* @param string $name
* @return mixed
*/
public function drop_field($table, $name) {
if (method_exists($this->db, 'dropField')) {
return $this->db->dropField($table, $name);
}
return $this->_drop_field_compat($table, $name);
}
/**
* @param string $table
* @param string $name
* @return bool
*/
protected function _drop_field_compat($table, $name) {
$table = $this->unquote_id((string) $table);
$name = $this->unquote_id((string) $name);
if ($table === '' || $name === '') {
return false;
}
return $this->_ddl_exec_mysql(
'ALTER TABLE '.$this->_mysql_qi($table).' DROP '.$this->_mysql_qi($name)
);
}
// 根据配置创建字段(字段类 create_sql 经驱动 sqlAddField 生成)
public function create_field($table, $config) {
if (!$config || !$table) {
return;
}
$tablename = $this->dbprefix($table);
foreach ($config as $field) {
if ($this->db->fieldExists($field['fieldname'], $tablename)) {
continue;
}
$obj = \Phpcmf\Service::L('field')->get($field['fieldtype']);
if (!$obj) {
continue;
}
$sql = $obj->create_sql($field['fieldname'], $field['setting']['option'], dr_safe_filename($field['name']));
if (!$sql) {
continue;
}
// create_sql 为 MySQL 源(含 {tablename}),走兼容执行
$sql = str_replace('{tablename}', $this->unquote_id($tablename), $sql);
$this->_ddl_exec_mysql($sql);
}
}
/**
* 创建表(优先驱动 createTable;未实现时拼 MySQL 源 SQL 经 formatCreateSql 兼容执行)
*
* @param string $table 表名(可含前缀)
* @param array $fields ['字段名'=>'类型属性'] 或 [0=>'完整列定义']
* @param array $indexs ['PRIMARY KEY (`id`)', 'KEY `name` (`name`)', ...]
* @param string $note 表注释
* @return array
*/
public function create_table($table, $fields, $indexs, $note) {
try {
if (method_exists($this->db, 'createTable')) {
$rt = $this->db->createTable($table, $fields, $indexs, $note);
if ($rt === false) {
$error = $this->db->error();
return dr_return_data(0, $error['message'] ?? 'createTable failed');
}
return dr_return_data(1);
}
return $this->_create_table_compat($table, $fields, $indexs, $note);
} catch (\Throwable $e) {
log_message('error', 'createTable: '.$e->getMessage());
return dr_return_data(0, $e->getMessage());
}
}
/**
* 驱动未实现 createTable 时的兼容建表
*
* @param string $table
* @param array $fields
* @param array $indexs
* @param string $note
* @return array
*/
protected function _create_table_compat($table, $fields, $indexs, $note) {
$table = $this->unquote_id((string) $table);
if ($table === '' || !is_array($fields) || !$fields) {
return dr_return_data(0, 'createTable 参数无效');
}
$lines = [];
foreach ($fields as $name => $def) {
if (is_int($name)) {
$lines[] = (string) $def;
} else {
$lines[] = $this->_mysql_qi($name).' '.(string) $def;
}
}
if (is_array($indexs)) {
foreach ($indexs as $idx) {
$idx = trim((string) $idx);
if ($idx !== '') {
$lines[] = $idx;
}
}
}
if (!$lines) {
return dr_return_data(0, 'createTable 无字段定义');
}
$sql = 'CREATE TABLE IF NOT EXISTS '.$this->_mysql_qi($table).' (
'.implode(",\n", $lines).'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT=\''
.str_replace("'", "''", (string) $note).'\'';
$rt = $this->_query_batch($sql);
if (empty($rt['code'])) {
return dr_return_data(0, $rt['msg'] ?? 'createTable compat failed');
}
return dr_return_data(1);
}
/**
* 删除表(优先驱动 dropTable;未实现时走兼容 SQL
*
* @param string $table
* @param bool $ifExists
* @return array
*/
public function drop_table($table, $ifExists = true) {
try {
if (method_exists($this->db, 'dropTable')) {
$rt = $this->db->dropTable($table, $ifExists);
} else {
$rt = $this->_drop_table_compat($table, $ifExists);
}
if ($rt === false) {
$error = $this->db->error();
return dr_return_data(0, $error['message'] ?? 'dropTable failed');
}
return dr_return_data(1);
} catch (\Throwable $e) {
log_message('error', 'dropTable: '.$e->getMessage());
return dr_return_data(0, $e->getMessage());
}
}
/**
* 驱动未实现 dropTable 时的兼容删除
*
* @param string $table
* @param bool $ifExists
* @return bool
*/
protected function _drop_table_compat($table, $ifExists = true) {
$table = $this->unquote_id((string) $table);
if ($table === '') {
return false;
}
if ($ifExists && method_exists($this->db, 'tableExists') && !$this->db->tableExists($table)) {
return true;
}
$sql = ($ifExists ? 'DROP TABLE IF EXISTS ' : 'DROP TABLE ').$this->_mysql_qi($table);
if ($this->_ddl_exec_mysql($sql)) {
return true;
}
// IF EXISTS 不被支持时退化
if ($ifExists) {
return $this->_ddl_exec_mysql('DROP TABLE '.$this->_mysql_qi($table));
}
return false;
}
/**
* 按 Schema 安装表结构与种子数据(Config/Install.php
*
* @param array $schema ['tables'=>[name=>['fields','indexes','comment','drop']], 'seeds'=>[['table','data']]]
* @return array
*/
public function install_schema(array $schema) {
$tables = isset($schema['tables']) && is_array($schema['tables']) ? $schema['tables'] : [];
$seeds = isset($schema['seeds']) && is_array($schema['seeds']) ? $schema['seeds'] : [];
foreach ($tables as $name => $def) {
if (!$name || !is_array($def) || empty($def['fields'])) {
continue;
}
$table = $this->dbprefix($name);
if (!empty($def['drop'])) {
$rt = $this->drop_table($table, true);
if (!$rt['code']) {
return $rt;
}
}
$rt = $this->create_table(
$table,
$def['fields'],
isset($def['indexes']) ? $def['indexes'] : [],
isset($def['comment']) ? $def['comment'] : ''
);
if (!$rt['code']) {
return dr_return_data(0, dr_lang('创建表失败(%s):%s', $table, $rt['msg']));
}
}
foreach ($seeds as $seed) {
if (empty($seed['table']) || empty($seed['data']) || !is_array($seed['data'])) {
continue;
}
$rt = \Phpcmf\Service::M()->table($seed['table'])->replace($seed['data']);
if (is_array($rt) && isset($rt['code']) && !$rt['code']) {
return dr_return_data(0, dr_lang('写入初始数据失败(%s):%s', $seed['table'], $rt['msg']));
}
}
return dr_return_data(1, '', ['tables' => dr_count($tables), 'seeds' => dr_count($seeds)]);
}
/**
* 获取建表 SQL(优先驱动 createTableSql
*
* @param string $table
* @return array [createSql, fieldFragments, table]
*/
public function create_table_sql($table) {
if (method_exists($this->db, 'createTableSql')) {
$create = $this->db->createTableSql($table);
} else {
$create = $this->_create_table_sql_compat($table);
}
if (!$create) {
return ['', [], $table];
}
$char = '`';
if (isset($this->db->escapeChar) && is_string($this->db->escapeChar) && $this->db->escapeChar !== '') {
$char = $this->db->escapeChar;
}
$quote = preg_quote($char, '/');
$arr = explode(PHP_EOL, $create);
$sql = [];
foreach ($arr as $t) {
if (preg_match('/'.$quote.'(.+)'.$quote.'/U', $t, $mt)
&& strpos($t, ' KEY ') === false
&& strpos($t, $char.$this->dbprefix()) === false
) {
$sql[$mt[1]] = trim($t, ',');
}
}
return [$create, $sql, $table];
}
/**
* 驱动未实现 createTableSql:先试 SHOW CREATE TABLE,再按字段元数据拼装
*
* @param string $table
* @return string
*/
protected function _create_table_sql_compat($table) {
$table = $this->unquote_id((string) $table);
if ($table === '') {
return '';
}
try {
$query = $this->db->query('SHOW CREATE TABLE '.$this->_mysql_qi($table));
$row = $query ? $query->getRowArray() : null;
if ($row) {
foreach ($row as $k => $v) {
if (stripos((string) $k, 'create') !== false && $v) {
return str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', (string) $v);
}
}
}
} catch (\Throwable $e) {
// 非 MySQL 忽略
}
if (!method_exists($this->db, 'getFieldData')) {
return '';
}
$fds = $this->db->getFieldData($table);
if (!$fds) {
return '';
}
$lines = [];
$pk = [];
foreach ($fds as $f) {
$name = isset($f->name) ? $f->name : '';
if ($name === '') {
continue;
}
$type = isset($f->type) ? $f->type : 'TEXT';
if (!empty($f->max_length) && !preg_match('/\(/', $type)
&& !preg_match('/(TEXT|BLOB|DATE|TIME|INT|FLOAT|DOUBLE|REAL|BOOL)/i', $type)
) {
$type .= '('.$f->max_length.')';
}
$null = (isset($f->nullable) ? $f->nullable : true) ? 'NULL' : 'NOT NULL';
$def = '';
if (isset($f->default) && $f->default !== null) {
$def = " DEFAULT '".str_replace("'", "''", (string) $f->default)."'";
}
$extra = '';
if (!empty($f->primary_key)) {
$pk[] = $this->_mysql_qi($name);
}
if (!empty($f->auto_increment)) {
$extra = ' AUTO_INCREMENT';
}
$lines[] = $this->_mysql_qi($name).' '.$type.' '.$null.$def.$extra;
}
if ($pk) {
$lines[] = 'PRIMARY KEY ('.implode(',', $pk).')';
}
return 'CREATE TABLE IF NOT EXISTS '.$this->_mysql_qi($table).' (
'.implode(",\n", $lines).'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci';
}
/**
* 从表结构导出规范化 Schemafields / indexes / comment
* 供 Dever 导出 Config/Content.php、Form.php 等使用
*/
public function create_table_schema($table) {
list($create) = $this->create_table_sql($table);
if (!$create) {
return [
'comment' => '',
'fields' => [],
'indexes' => [],
];
}
$comment = '';
if (preg_match("/COMMENT='([^']*)'/", $create, $cm)) {
$comment = $cm[1];
} elseif (preg_match('/COMMENT="([^"]*)"/', $create, $cm)) {
$comment = $cm[1];
}
$inner = $create;
if (preg_match('/\((.*)\)\s*ENGINE/is', $create, $m)) {
$inner = $m[1];
}
$fields = [];
$indexes = [];
$parts = preg_split("/,\s*\n/", trim($inner));
if (dr_count($parts) < 2) {
$parts = [];
$buf = '';
$depth = 0;
$len = strlen($inner);
for ($i = 0; $i < $len; $i++) {
$ch = $inner[$i];
if ($ch === '(') {
$depth++;
$buf .= $ch;
} elseif ($ch === ')') {
$depth = max(0, $depth - 1);
$buf .= $ch;
} elseif ($ch === ',' && $depth === 0) {
$parts[] = trim($buf);
$buf = '';
} else {
$buf .= $ch;
}
}
if (trim($buf) !== '') {
$parts[] = trim($buf);
}
}
foreach ($parts as $line) {
$line = trim($line);
$line = rtrim($line, ',');
if ($line === '') {
continue;
}
if (preg_match('/^(PRIMARY KEY|UNIQUE KEY|KEY|FULLTEXT KEY)\s/i', $line)) {
$indexes[] = $line;
continue;
}
if (preg_match('/^`([^`]+)`\s+(.+)$/s', $line, $fm)) {
$fields[$fm[1]] = trim($fm[2]);
}
}
return [
'comment' => $comment,
'fields' => $fields,
'indexes' => $indexes,
];
}
/**
* 表完整字段信息(优先驱动 showFullColunms
*
* @param string $table
* @return array
*/
public function show_full_colunms($table) {
if (method_exists($this->db, 'showFullColunms')) {
return $this->db->showFullColunms($table);
}
return $this->_show_full_colunms_compat($table);
}
/**
* @param string $table
* @return array
*/
protected function _show_full_colunms_compat($table) {
$table = $this->unquote_id((string) $table);
if ($table === '') {
return [];
}
try {
$query = $this->db->query('SHOW FULL COLUMNS FROM '.$this->_mysql_qi($table));
if ($query) {
$rows = $query->getResultArray();
if ($rows) {
return $rows;
}
}
} catch (\Throwable $e) {
// 非 MySQL
}
if (!method_exists($this->db, 'getFieldData')) {
return [];
}
$out = [];
foreach ($this->db->getFieldData($table) as $f) {
$out[] = [
'Field' => isset($f->name) ? $f->name : '',
'Type' => isset($f->type) ? $f->type : '',
'Collation' => null,
'Null' => (isset($f->nullable) && !$f->nullable) ? 'NO' : 'YES',
'Key' => !empty($f->primary_key) ? 'PRI' : '',
'Default' => isset($f->default) ? $f->default : null,
'Extra' => !empty($f->auto_increment) ? 'auto_increment' : '',
'Privileges' => '',
'Comment' => '',
];
}
return $out;
}
/**
* 全部表状态(优先驱动 showTableStatus
*
* @return array
*/
public function show_table_status() {
if (method_exists($this->db, 'showTableStatus')) {
return $this->db->showTableStatus();
}
return $this->_show_table_status_compat();
}
/**
* @return array
*/
protected function _show_table_status_compat() {
try {
$query = $this->db->query('SHOW TABLE STATUS');
if ($query) {
$rows = $query->getResultArray();
if ($rows) {
return $rows;
}
}
} catch (\Throwable $e) {
// 非 MySQL
}
$out = [];
if (method_exists($this->db, 'listTables')) {
foreach ($this->db->listTables() as $name) {
$out[] = [
'Name' => $name,
'Engine' => '',
'Version' => '',
'Row_format' => '',
'Rows' => 0,
'Avg_row_length' => 0,
'Data_length' => 0,
'Max_data_length' => 0,
'Index_length' => 0,
'Data_free' => 0,
'Auto_increment' => null,
'Create_time' => null,
'Update_time' => null,
'Check_time' => null,
'Collation' => '',
'Checksum' => null,
'Create_options' => '',
'Comment' => '',
];
}
}
return $out;
}
/**
* 修复表(优先驱动;兼容执行 MySQL REPAIR TABLE,失败则视为跳过成功)
*
* @param string $table
* @return mixed
*/
public function repair_table($table) {
if (method_exists($this->db, 'repairTable')) {
return $this->db->repairTable($table);
}
return $this->_maintenance_table_compat('REPAIR TABLE', $table);
}
/**
* 优化表
*
* @param string $table
* @return mixed
*/
public function optimize_table($table) {
if (method_exists($this->db, 'optimizeTable')) {
return $this->db->optimizeTable($table);
}
return $this->_maintenance_table_compat('OPTIMIZE TABLE', $table);
}
/**
* 刷新表
*
* @param string $table
* @return mixed
*/
public function flush_table($table) {
if (method_exists($this->db, 'flushTable')) {
return $this->db->flushTable($table);
}
return $this->_maintenance_table_compat('FLUSH TABLE', $table);
}
/**
* 检查表
*
* @param string $table
* @return array
*/
public function check_table($table) {
if (method_exists($this->db, 'checkTable')) {
return $this->db->checkTable($table);
}
$table = $this->unquote_id((string) $table);
if ($table === '') {
return [];
}
try {
$query = $this->db->query('CHECK TABLE '.$this->_mysql_qi($table));
$row = $query ? $query->getRowArray() : null;
if ($row) {
return $row;
}
} catch (\Throwable $e) {
// 非 MySQL:返回通过状态,避免后台报错
}
return ['Msg_text' => 'OK', 'Msg_type' => 'status'];
}
/**
* MySQL 维护类语句兼容(不支持的库跳过并返回 true)
*
* @param string $verb REPAIR TABLE / OPTIMIZE TABLE / FLUSH TABLE
* @param string $table
* @return bool
*/
protected function _maintenance_table_compat($verb, $table) {
$table = $this->unquote_id((string) $table);
if ($table === '') {
return false;
}
try {
$rt = $this->db->query($verb.' '.$this->_mysql_qi($table));
if ($rt !== false) {
return $rt;
}
} catch (\Throwable $e) {
// ignore
}
return true;
}
/**
* 修改表默认字符集(优先驱动 setTableCharset
*
* @param string $table
* @param string $charset
* @param string $collate
* @return mixed
*/
public function set_table_charset($table, $charset = 'utf8mb4', $collate = 'utf8mb4_unicode_ci') {
if (method_exists($this->db, 'setTableCharset')) {
return $this->db->setTableCharset($table, $charset, $collate);
}
return $this->_set_table_charset_compat($table, $charset, $collate);
}
/**
* @param string $table
* @param string $charset
* @param string $collate
* @return bool
*/
protected function _set_table_charset_compat($table, $charset = 'utf8mb4', $collate = 'utf8mb4_unicode_ci') {
$table = $this->unquote_id((string) $table);
if ($table === '') {
return false;
}
$charset = preg_replace('/[^a-z0-9_]/i', '', (string) $charset);
$collate = preg_replace('/[^a-z0-9_]/i', '', (string) $collate);
$sql = 'ALTER TABLE '.$this->_mysql_qi($table).' DEFAULT CHARSET='.$charset.' COLLATE '.$collate;
if ($this->_ddl_exec_mysql($sql)) {
return true;
}
// 不支持字符集的库视为跳过
return true;
}
/**
* 创建索引(优先驱动;否则 MySQL CREATE INDEX 经 formatCreateSql
*
* @param string $table
* @param string $name
* @param string|array $columns
* @return mixed
*/
public function add_index($table, $name, $columns) {
$table = $this->unquote_id((string) $table);
$name = $this->unquote_id((string) $name);
if ($table === '' || $name === '') {
return false;
}
if (is_array($columns)) {
$cols = [];
foreach ($columns as $c) {
$cols[] = $this->_mysql_qi($c);
}
$colsql = implode(', ', $cols);
} else {
$colsql = (string) $columns;
if (!$this->has_id_quotes($colsql)) {
$parts = array_map('trim', explode(',', $colsql));
$tmp = [];
foreach ($parts as $p) {
$p !== '' && $tmp[] = $this->_mysql_qi($p);
}
$colsql = implode(', ', $tmp);
}
}
if (method_exists($this->db, 'addIndex')) {
return $this->db->addIndex($table, $name, $columns);
}
return $this->_ddl_exec_mysql(
'CREATE INDEX '.$this->_mysql_qi($name).' ON '.$this->_mysql_qi($table).'('.$colsql.')'
);
}
// 表结构缓存
public function cache($siteid = SITE_ID, $module = null) {
$cache = [];
$paytable = []; // 付款表名 支持模块和表单 后期淘汰
// 生成模块表结构
if (dr_is_use_module()) {
$obj = \Phpcmf\Service::M('module', 'cms');
if (method_exists($obj, 'paytable')) {
list($cache, $paytable) = $obj->paytable($cache, $paytable, $module, $siteid);
}
}
// 网站表单
if (dr_is_app('form') && $this->is_table_exists($siteid.'_form')) {
$obj = \Phpcmf\Service::M('form', 'form');
if (method_exists($obj, 'paytable')) {
list($cache, $paytable) = $obj->paytable($cache, $paytable, $siteid);
}
}
// 会员表
$table = $this->dbprefix('member');
$cache[$table] = $this->db->getFieldNames($table);
// 会员附表
$table = $this->dbprefix('member_data');
$cache[$table] = $this->db->getFieldNames($table);
// 缓存表结构
\Phpcmf\Service::L('cache')->set_file('table-'.$siteid, $cache);
// 缓存的字段类型
//$type = ['Select', 'Checkbox', 'Radio', 'Pay', 'Pays', 'File', 'Files', 'Image', 'Images', 'Ftable'];
$cache = [];
$field = $this->db->table('field')->where('disabled', 0)->orderBy('id ASC')->get()->getResultArray();
if ($field) {
foreach ($field as $f) {
$f['setting'] = dr_string2array($f['setting']);
$cache[$f['id']] = $f;
}
}
\Phpcmf\Service::L('cache')->set_file('table-field', $cache);
// 缓存付款表
\Phpcmf\Service::L('cache')->set_file('table-pay-'.$siteid, $paytable);
/*
* $paytable字段主键为 自定义字段rname-rid
* */
}
// 获取字段结构
public function get_field($table) {
return $this->db->getFieldNames($this->dbprefix($table));
}
// 获取缓存的字段结构
public function get_cache_field($table) {
$tableinfo = \Phpcmf\Service::L('cache')->get('table-'.SITE_ID);
if (!$tableinfo) {
// 没有表结构缓存时返回空
return [];
}
return isset($tableinfo[$this->dbprefix($table)]) ? $tableinfo[$this->dbprefix($table)] : [];
}
// 执行批量sql
public function _query($sql, $replace = []) {
return $this->_query_batch($sql, $replace);
}
// 网站表单--------------------------------------------------------------------
// 创建
public function create_form($data) {
if (dr_is_app('form')) {
\Phpcmf\Service::M('form', 'form')->create_form($data);
}
}
// 删除表单
public function delete_form($data) {
if (dr_is_app('form')) {
\Phpcmf\Service::M('form', 'form')->delete_form_table($data);
}
}
// 模块表单--------------------------------------------------------------------
// 创建
public function create_module_form($data) {
if (dr_is_app('mform')) {
\Phpcmf\Service::M('mform', 'mform')->create_module_form($data);
}
}
// 删除模块表单
public function delete_module_form($data) {
if (dr_is_app('mform')) {
\Phpcmf\Service::M('mform', 'mform')->delete_module_form($data);
}
}
// 项目--------------------------------------------------------------------
// 创建项目
public function create_site($siteid) {
}
}