2102 lines
63 KiB
PHP
2102 lines
63 KiB
PHP
<?php namespace Phpcmf;
|
||
/**
|
||
* https://www.besyun.com
|
||
* BESCMS
|
||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||
**/
|
||
|
||
if (is_file(MYPATH.'Extend/Model.php')) {
|
||
require MYPATH.'Extend/Model.php';
|
||
} else {
|
||
require FRAMEPATH.'Extend/Model.php';
|
||
}
|
||
|
||
// 模型类
|
||
class Model {
|
||
|
||
public $db;
|
||
public $prefix;
|
||
|
||
public $id = 'id';
|
||
public $key = 'id';
|
||
|
||
public $site;
|
||
|
||
public $field;
|
||
public $siteid;
|
||
public $table;
|
||
public $mytable;
|
||
public $stable; // join关联表
|
||
public $sfield; // join关联表的字段
|
||
public $db_temp; // 备份默认数据库
|
||
|
||
public $uid;
|
||
public $admin;
|
||
public $member;
|
||
|
||
protected $date_field;
|
||
protected $param;
|
||
protected $init;
|
||
|
||
public function __construct() {
|
||
|
||
list($this->db, $this->prefix) = \Frame\Model::_load_db();
|
||
|
||
$this->uid = \Phpcmf\Service::C()->uid;
|
||
$this->site = \Phpcmf\Service::C()->site;
|
||
$this->admin = \Phpcmf\Service::C()->admin;
|
||
$this->member = \Phpcmf\Service::C()->member;
|
||
$this->siteid = defined('SITE_ID') ? SITE_ID : 0;
|
||
}
|
||
|
||
// 设置初始化查询条件
|
||
public function init($data) {
|
||
|
||
isset($data['id']) && $this->id = $this->key = $data['id'];
|
||
isset($data['table']) && $this->table = $data['table'];
|
||
isset($data['stable']) && $this->stable = $data['stable'];
|
||
isset($data['sfield']) && $this->sfield = $data['sfield'];
|
||
isset($data['field']) && $this->field = $data['field'];
|
||
isset($data['date_field']) && $this->date_field = $data['date_field'];
|
||
|
||
isset($data['order_by']) && $this->param['order_list'] = $data['order_by'];
|
||
isset($data['group_by']) && $this->param['group_list'] = $data['group_by'];
|
||
isset($data['order_list']) && $this->param['order_list'] = $data['order_list'];
|
||
isset($data['where_list']) && $this->param['where_list'] = $data['where_list'];
|
||
isset($data['is_diy_where_list']) && $this->param['is_diy_where_list'] = $data['is_diy_where_list'];
|
||
isset($data['join_list']) && $this->param['join_list'] = $data['join_list'];
|
||
isset($data['select_list']) && $this->param['select_list'] = $data['select_list'];
|
||
|
||
$this->init = $data; // 方便调用
|
||
|
||
return $this;
|
||
}
|
||
|
||
// 设置列表搜索条件
|
||
public function set_where_list($where) {
|
||
$this->param['where_list'] = $where;
|
||
}
|
||
|
||
// 追加列表搜索条件
|
||
public function add_where_list($where) {
|
||
$this->param['where'][] = $where;
|
||
}
|
||
|
||
// 设置操作主键
|
||
public function id($id = '') {
|
||
if ($id) {
|
||
$this->key = $id;
|
||
} else {
|
||
$this->key = $this->id;
|
||
}
|
||
return $this;
|
||
}
|
||
|
||
// 设置数据源
|
||
public function db_source($name = '') {
|
||
if ($name) {
|
||
$this->db_temp = $this->db;
|
||
list($this->db, $this->prefix) = \Frame\Model::_load_db_source($name);
|
||
}
|
||
return $this;
|
||
}
|
||
|
||
// 设置操作表
|
||
public function table($name) {
|
||
$this->table = $name;
|
||
return $this;
|
||
}
|
||
|
||
// 设置操作站点的表
|
||
public function table_site($name, $site = 0) {
|
||
if (!$site) {
|
||
$site = $this->siteid ? $this->siteid : SITE_ID;
|
||
}
|
||
$this->table = dr_site_table_prefix($name, $site);
|
||
return $this;
|
||
}
|
||
|
||
// 获取表前缀
|
||
public function dbprefix($name = '') {
|
||
return $this->prefix.$name;
|
||
}
|
||
|
||
// 执行sql
|
||
public function query($sql) {
|
||
|
||
if (!$this->db->simpleQuery($sql)) {
|
||
$error = $this->db->error();
|
||
$this->_clear();
|
||
log_message('error', $sql.': '.$error['message'].'<br>'.FC_NOW_URL);
|
||
return $this->_return_error($error['message']);
|
||
}
|
||
|
||
$this->_clear();
|
||
return dr_return_data(1);
|
||
}
|
||
|
||
// 附表不存在时创建附表
|
||
public function is_data_table($table, $tid) {
|
||
if ($tid > 0 && !$this->is_table_exists($this->dbprefix($table.$tid))) {
|
||
// 附表不存在时创建附表
|
||
list($a, $sql, $name) = \Phpcmf\Service::M('table')->create_table_sql($this->dbprefix($table).'0');
|
||
$this->query(str_replace(
|
||
[$name, 'CREATE TABLE '],
|
||
[$this->dbprefix($table.$tid), 'CREATE TABLE IF NOT EXISTS '],
|
||
$a
|
||
));
|
||
}
|
||
$this->_clear();
|
||
}
|
||
|
||
// 表是否存在
|
||
public function is_table_exists($table) {
|
||
|
||
if (!$table) {
|
||
$this->_clear();
|
||
return 0;
|
||
}
|
||
|
||
$table = strpos($table, $this->prefix) === 0 ? $table : $this->dbprefix($table);
|
||
$rt = $this->db->tableExists($table) ? 1 : 0;
|
||
|
||
$this->_clear();
|
||
|
||
return $rt;
|
||
}
|
||
|
||
// 表字段是否存在
|
||
public function is_field_exists($table, $name) {
|
||
|
||
if (!$table || !$name) {
|
||
$this->_clear();
|
||
return 0;
|
||
}
|
||
|
||
$table = strpos($table, $this->prefix) === 0 ? $table : $this->dbprefix($table);
|
||
$rt = $this->db->fieldExists($name, $table) ? 1 : 0;
|
||
$this->_clear();
|
||
|
||
return $rt;
|
||
}
|
||
|
||
// 字段值是否存在
|
||
public function is_exists($id, $name, $value) {
|
||
|
||
$builder = $this->db->table($this->table);
|
||
|
||
// 条件
|
||
if ($this->param['where']) {
|
||
foreach ($this->param['where'] as $v) {
|
||
dr_count($v) == 2 ? $builder->where($v[0], $v[1]) : $builder->where($v, null, false);
|
||
}
|
||
}
|
||
|
||
// in条件
|
||
if ($this->param['where_in']) {
|
||
foreach ($this->param['where_in'] as $v) {
|
||
dr_count($v) == 2 ? $builder->whereIn($v[0], $v[1]) : $builder->whereIn($v, null, false);
|
||
}
|
||
}
|
||
|
||
$rt = $builder->where($name, $value)->where($this->key.'<>'. $id)->countAllResults();
|
||
|
||
$this->_clear();
|
||
|
||
return $rt;
|
||
}
|
||
|
||
|
||
// 统计数量
|
||
public function counts($table = '', $where = '') {
|
||
|
||
$table = !$table ? $this->table : $table;
|
||
if (!$table) {
|
||
return 0;
|
||
}
|
||
|
||
$builder = $this->db->table($table);
|
||
|
||
// 条件
|
||
if ($this->param['where']) {
|
||
foreach ($this->param['where'] as $v) {
|
||
dr_count($v) == 2 ? $builder->where($v[0], $v[1]) : $builder->where($v, null, false);
|
||
}
|
||
}
|
||
|
||
// in条件
|
||
if ($this->param['where_in']) {
|
||
foreach ($this->param['where_in'] as $v) {
|
||
dr_count($v) == 2 ? $builder->whereIn($v[0], $v[1]) : $builder->whereIn($v, null, false);
|
||
}
|
||
}
|
||
|
||
// 分组
|
||
$this->param['group'] && $builder->groupBy($this->param['group']);
|
||
|
||
$where && $builder->where($where);
|
||
|
||
$this->_clear();
|
||
|
||
return $builder->countAllResults();
|
||
}
|
||
|
||
// 插入数据
|
||
public function insert($data) {
|
||
|
||
$this->db->table($this->table)->insert($data);
|
||
$rt = $this->db->error();
|
||
if ($rt['code']) {
|
||
$this->_clear();
|
||
log_message('error', $this->table.': '.$rt['message'].'<br>'.FC_NOW_URL);
|
||
return $this->_return_error($this->table.': '.$rt['message']);
|
||
}
|
||
|
||
$id = $this->db->insertID();
|
||
!$id && $id = intval($data[$this->key]);
|
||
|
||
if (!$id) {
|
||
$this->_clear();
|
||
log_message('debug', $this->table.': 主键获取失败<br>'.FC_NOW_URL);
|
||
return $this->_return_error($this->table.': 主键获取失败');
|
||
}
|
||
|
||
$this->_clear();
|
||
|
||
return dr_return_data($id);
|
||
}
|
||
|
||
// 插入数据
|
||
public function replace($data) {
|
||
|
||
$this->db->table($this->table)->replace($data);
|
||
$rt = $this->db->error();
|
||
if ($rt['code']) {
|
||
$this->_clear();
|
||
log_message('error', $this->table.': '.$rt['message'].'<br>'.FC_NOW_URL);
|
||
return $this->_return_error($this->table.': '.$rt['message']);
|
||
}
|
||
|
||
$id = $this->db->insertID();
|
||
!$id && $id = intval($data[$this->key]);
|
||
|
||
if (!$id) {
|
||
$this->_clear();
|
||
log_message('debug', $this->table.': 主键获取失败<br>'.FC_NOW_URL);
|
||
return $this->_return_error($this->table.': 主键获取失败');
|
||
}
|
||
|
||
$this->_clear();
|
||
|
||
return dr_return_data($id);
|
||
}
|
||
|
||
// 批量插入
|
||
public function insert_batch($data) {
|
||
|
||
if (!$this->table || !$data) {
|
||
return;
|
||
}
|
||
|
||
$rt = $this->db->table($this->table)->insertBatch($data);
|
||
|
||
$this->_clear();
|
||
|
||
return $rt;
|
||
}
|
||
|
||
// 批量更新
|
||
public function update_batch($data, $key = 'id') {
|
||
|
||
if (!$this->table || !$data) {
|
||
return;
|
||
}
|
||
|
||
$this->db->table($this->table)->updateBatch($data, $key ? $key : $this->key);
|
||
|
||
$this->_clear();
|
||
}
|
||
|
||
// 更新数据
|
||
public function update($id, $data, $where = '') {
|
||
|
||
if (!$data) {
|
||
$this->_clear();
|
||
return $this->_return_error($this->table.': update() data值为空');
|
||
}
|
||
|
||
$db = $this->db->table($this->table);
|
||
$id && $db->where($this->key, (int)$id);
|
||
|
||
$where && $db->where($where, null, false);
|
||
|
||
// 条件
|
||
if ($this->param['where']) {
|
||
foreach ($this->param['where'] as $v) {
|
||
dr_count($v) == 2 ? $db->where($v[0], $v[1]) : $db->where($v, null, false);
|
||
}
|
||
}
|
||
|
||
// in条件
|
||
if ($this->param['where_in']) {
|
||
foreach ($this->param['where_in'] as $v) {
|
||
dr_count($v) == 2 ? $db->whereIn($v[0], $v[1]) : $db->whereIn($v, null, false);
|
||
}
|
||
}
|
||
|
||
$db->update($data);
|
||
|
||
$rt = $this->db->error();
|
||
if ($rt['code']) {
|
||
$this->_clear();
|
||
log_message('error', $this->table.': '.$rt['message'].'<br>'.FC_NOW_URL);
|
||
return $this->_return_error($this->table.': '.$rt['message']);
|
||
}
|
||
|
||
$this->_clear();
|
||
|
||
return dr_return_data($id);
|
||
}
|
||
|
||
// 删除数据
|
||
/*
|
||
* 主键
|
||
* */
|
||
public function delete($id = 0 , $where = '') {
|
||
|
||
$db = $this->db->table($this->table);
|
||
|
||
$where && $db->where($where, null, false);
|
||
$id && $db->where($this->key, (int)$id);
|
||
|
||
// 条件
|
||
if ($this->param['where']) {
|
||
foreach ($this->param['where'] as $v) {
|
||
dr_count($v) == 2 ? $db->where($v[0], $v[1]) : $db->where($v, null, false);
|
||
}
|
||
}
|
||
|
||
// in条件
|
||
if ($this->param['where_in']) {
|
||
foreach ($this->param['where_in'] as $v) {
|
||
dr_count($v) == 2 ? $db->whereIn($v[0], $v[1]) : $db->whereIn($v, null, false);
|
||
}
|
||
}
|
||
|
||
// 执行删除
|
||
$db->delete();
|
||
|
||
$rt = $this->db->error();
|
||
if ($rt['code']) {
|
||
$this->_clear();
|
||
log_message('error', $this->table.': '.$rt['message'].'<br>'.FC_NOW_URL);
|
||
return $this->_return_error($this->table.': '.$rt['message']);
|
||
}
|
||
|
||
$this->_clear();
|
||
|
||
return dr_return_data(1);
|
||
}
|
||
|
||
// 执行”写入”类型的语句(insert,update等)时返回有多少行受影响
|
||
public function affected_rows() {
|
||
return $this->db->affectedRows();
|
||
}
|
||
|
||
// 启动事务
|
||
public function trans_start(){
|
||
$this->db->transBegin();
|
||
}
|
||
|
||
// 回滚事务
|
||
public function trans_rollback(){
|
||
$this->db->transRollback();
|
||
}
|
||
|
||
// 执行事务提交
|
||
public function trans_comment(){
|
||
if ($this->db->transStatus() === FALSE) {
|
||
$this->db->transRollback();
|
||
return false;
|
||
} else {
|
||
$this->db->transCommit();
|
||
return true;
|
||
}
|
||
}
|
||
|
||
// 删除全部内容
|
||
public function clear_all() {
|
||
return $this->db->table($this->table)->truncate();
|
||
}
|
||
|
||
// 批量删除数据
|
||
/*
|
||
* 主键数组
|
||
* */
|
||
public function delete_all($ids, $where = '') {
|
||
$this->deleteAll($ids, $where);
|
||
}
|
||
public function deleteAll($ids, $where = '') {
|
||
|
||
$db = $this->db->table($this->table);
|
||
$where && $db->where($where, null, false);
|
||
|
||
// 条件
|
||
if ($this->param['where']) {
|
||
foreach ($this->param['where'] as $v) {
|
||
dr_count($v) == 2 ? $db->where($v[0], $v[1]) : $db->where($v, null, false);
|
||
}
|
||
}
|
||
|
||
// in条件
|
||
if ($this->param['where_in']) {
|
||
foreach ($this->param['where_in'] as $v) {
|
||
dr_count($v) == 2 ? $db->whereIn($v[0], $v[1]) : $db->whereIn($v, null, false);
|
||
}
|
||
}
|
||
|
||
$db->whereIn($this->key, (array)$ids)->delete();
|
||
|
||
$rt = $this->db->error();
|
||
if ($rt['code']) {
|
||
$this->_clear();
|
||
log_message('error', $this->table.': '.$rt['message'].'<br>'.FC_NOW_URL);
|
||
return $this->_return_error($this->table.': '.$rt['message']);
|
||
}
|
||
|
||
|
||
$this->_clear();
|
||
|
||
return dr_return_data(1);
|
||
}
|
||
|
||
/*
|
||
* 保存单个数据
|
||
* 主键
|
||
* 字段名
|
||
* 字段值
|
||
* */
|
||
public function save($id, $name, $value, $where = '') {
|
||
|
||
$db = $this->db->table($this->table);
|
||
$where && $db->where($where, null, false);
|
||
$db->where($this->key, (int)$id)->update([$name => $value]);
|
||
|
||
$rt = $this->db->error();
|
||
if ($rt['code']) {
|
||
$this->_clear();
|
||
return $this->_return_error($this->table.': '.$rt['message']);
|
||
}
|
||
|
||
$this->_clear();
|
||
|
||
return dr_return_data($id);
|
||
}
|
||
|
||
/*
|
||
* 获取单个数据
|
||
* 主键
|
||
* */
|
||
public function get($id) {
|
||
|
||
$query = $this->db->table($this->table)->where($this->key, (int)$id)->get();
|
||
if (!$query) {
|
||
$this->_clear();
|
||
return [];
|
||
}
|
||
|
||
$rt = $query->getRowArray();
|
||
$this->_clear();
|
||
|
||
return $rt;
|
||
}
|
||
|
||
/*
|
||
* 获取全部数据
|
||
* 指定数量
|
||
* 数组主键id
|
||
* */
|
||
public function get_all($num = 0, $key = '') {
|
||
return $this->getAll($num, $key);
|
||
}
|
||
public function getAll($num = 0, $key = '') {
|
||
|
||
$builder = $this->db->table($this->table);
|
||
|
||
// 条件
|
||
if ($this->param['where']) {
|
||
foreach ($this->param['where'] as $v) {
|
||
dr_count($v) == 2 ? $builder->where($v[0], $v[1]) : $builder->where($v, null, false);
|
||
}
|
||
}
|
||
|
||
// in条件
|
||
if ($this->param['where_in']) {
|
||
foreach ($this->param['where_in'] as $v) {
|
||
dr_count($v) == 2 ? $builder->whereIn($v[0], $v[1]) : $builder->whereIn($v, null, false);
|
||
}
|
||
}
|
||
|
||
// select字段
|
||
$this->_apply_builder_select($builder);
|
||
|
||
// 排序
|
||
$this->param['order'] && $builder->orderBy($this->param['order']);
|
||
|
||
// 分组
|
||
$this->param['group'] && $builder->groupBy($this->param['group']);
|
||
|
||
// 数量控制
|
||
if ($this->param['limit']) {
|
||
list($a, $b) = explode(',', $this->param['limit']);
|
||
if ($b) {
|
||
$builder->limit($a, $b);
|
||
} else {
|
||
$builder->limit($a);
|
||
}
|
||
} elseif ($num) {
|
||
$builder->limit($num);
|
||
}
|
||
|
||
$query = $builder->get();
|
||
if (!$query) {
|
||
$this->_clear();
|
||
return [];
|
||
}
|
||
|
||
$rt = $query->getResultArray();
|
||
if ($rt && $key) {
|
||
$rt2 = $rt;
|
||
$rt = [];
|
||
foreach ($rt2 as $i => $t) {
|
||
$rt[(isset($t[$key]) ? $t[$key] : $i)] = $t;
|
||
}
|
||
}
|
||
|
||
$this->_clear();
|
||
|
||
return $rt;
|
||
}
|
||
|
||
/*
|
||
* 获取单个数据
|
||
* */
|
||
public function getRow() {
|
||
|
||
$builder = $this->db->table($this->table);
|
||
|
||
// 条件
|
||
if ($this->param['where']) {
|
||
foreach ($this->param['where'] as $v) {
|
||
dr_count($v) == 2 ? $builder->where($v[0], $v[1]) : $builder->where($v, null, false);
|
||
}
|
||
}
|
||
|
||
// in条件
|
||
if ($this->param['where_in']) {
|
||
foreach ($this->param['where_in'] as $v) {
|
||
dr_count($v) == 2 ? $builder->whereIn($v[0], $v[1]) : $builder->whereIn($v, null, false);
|
||
}
|
||
}
|
||
|
||
// select字段
|
||
$this->_apply_builder_select($builder);
|
||
|
||
if (!$builder) {
|
||
$this->_clear();
|
||
return [];
|
||
}
|
||
|
||
// 排序
|
||
$this->param['order'] && $builder->orderBy($this->param['order']);
|
||
|
||
// 分组
|
||
$this->param['group'] && $builder->groupBy($this->param['group']);
|
||
|
||
$builder->limit(1);
|
||
|
||
$rt = $builder->get();
|
||
|
||
$data = [];
|
||
$rt && $data = $rt->getRowArray();
|
||
|
||
$this->_clear();
|
||
|
||
return $data;
|
||
}
|
||
|
||
/*
|
||
* 获取单个字段值
|
||
* */
|
||
public function getField($name) {
|
||
$data = $this->getRow();
|
||
return isset($data[$name]) ? $data[$name] : '';
|
||
}
|
||
|
||
/*
|
||
* 操作数据
|
||
* 数据不存在-1, 变更值0, 变更至1
|
||
* */
|
||
public function used($id, $name) {
|
||
|
||
$data = $this->db->table($this->table)->select($name)->where('id', (int)$id)->get()->getRowArray();
|
||
|
||
if ($data) {
|
||
$value = $data[$name] ? 0 : 1;
|
||
// 更新
|
||
$this->db->table($this->table)->where('id', $id)->update([$name => $value]);
|
||
$this->_clear();
|
||
return $value;
|
||
}
|
||
|
||
$this->_clear();
|
||
return -1;
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////
|
||
|
||
// 条件组合(按字段类型分发到 where_field_*)
|
||
public function _where($table, $name, $value, $field, $is_like = false) {
|
||
|
||
if (!$value && dr_strlen($value) == 0) {
|
||
return ''; //空值
|
||
}
|
||
|
||
$name = dr_safe_replace($name, ['\\', '/']);
|
||
$ft = isset($field['fieldtype']) ? $field['fieldtype'] : '';
|
||
|
||
if ($ft == 'Date' || in_array($name, ['inputtime', 'updatetime'])) {
|
||
list($s, $e) = explode(',', (string) $value);
|
||
$s = (int) strtotime((string) $s);
|
||
$e = (int) strtotime((string) $e);
|
||
if ($s == $e && $s == 0) {
|
||
return '';
|
||
}
|
||
$col = $this->_where_field_col($table, $name);
|
||
// 无结束日期:开区间(各库语法一致,不必走驱动)
|
||
if (!$e) {
|
||
return $col.' > '.$s;
|
||
}
|
||
return $this->where_between($col, $s, $e);
|
||
}
|
||
if ($ft == 'File' && isset($field['fieldname']) && $field['fieldname'] == 'thumb' && $value == 1) {
|
||
return $this->where_field_thumb($table, $name, $value);
|
||
}
|
||
if ($ft && strpos($ft, 'map') !== false) {
|
||
return $this->where_field_map($table, $name, $value);
|
||
}
|
||
if ($ft == 'Diy'
|
||
&& !empty($field['setting']['option']['file'])
|
||
&& function_exists('dr_diy_field_'.substr($field['setting']['option']['file'], 0, -4).'_search')) {
|
||
return $this->where_field_diy($table, $name, $value, $field);
|
||
}
|
||
if ($ft == 'Linkage') {
|
||
return $this->where_field_linkage($table, $name, $value, $field, $is_like);
|
||
}
|
||
if ($ft == 'Linkages') {
|
||
return $this->where_field_linkages($table, $name, $value, $field, $is_like);
|
||
}
|
||
if (in_array($ft, ['Selects', 'Checkbox', 'Cats'])) {
|
||
return $this->where_field_checkbox($table, $name, $value, $field, $is_like);
|
||
}
|
||
if (in_array($ft, ['Members', 'Related'])) {
|
||
return $this->where_field_members($table, $name, $value);
|
||
}
|
||
if (in_array($ft, ['Radio', 'Select'])) {
|
||
return $this->where_field_select($table, $name, $value, $field, $is_like);
|
||
}
|
||
if (substr_count($value, ',') == 1 && preg_match('/[\+\-0-9\.]+,[\+\-0-9\.]+/', $value)) {
|
||
list($s, $e) = explode(',', (string) $value);
|
||
$s = floatval($s);
|
||
$e = floatval($e);
|
||
$col = $this->_where_field_col($table, $name);
|
||
if ($s == $e && $s == 0) {
|
||
return $col.' = 0';
|
||
}
|
||
if (!$e && $s > 0) {
|
||
return $col.' > '.$s;
|
||
}
|
||
if (!$e) {
|
||
$e = 0;
|
||
}
|
||
return $this->where_between($col, $s, $e);
|
||
}
|
||
if ($is_like || strpos($value, '%') !== false || strpos($value, ' ') !== false) {
|
||
return $this->where_field_like($table, $name, $value);
|
||
}
|
||
|
||
return $this->where_field_eq($table, $name, $value);
|
||
}
|
||
|
||
protected function _limit_where(&$select, $param, $field, $table) {
|
||
|
||
$table = $this->dbprefix($table);
|
||
if (isset($param['keyword']) && $param['keyword']) {
|
||
$param['keyword'] = htmlspecialchars(urldecode($param['keyword']));
|
||
}
|
||
|
||
$fname = $param['field'];
|
||
$kw = $param['keyword'];
|
||
$finfo = isset($field[$fname]) && is_array($field[$fname]) ? $field[$fname] : [];
|
||
$ft = isset($finfo['fieldtype']) ? $finfo['fieldtype'] : '';
|
||
|
||
if ($fname == $this->id) {
|
||
$sql = $this->where_limit_id($table, $this->id, $kw);
|
||
} elseif (!empty($finfo['myfunc'])) {
|
||
$sql = $this->where_limit_myfunc($param, $finfo);
|
||
} elseif ($fname == 'uid' || $ft == 'Uid') {
|
||
$sql = $this->where_limit_uid($table, $fname, $kw);
|
||
} elseif ($ft == 'INT' || !empty($finfo['isint'])) {
|
||
$sql = $this->where_limit_int($table, $fname, $kw);
|
||
} elseif (!empty($finfo['isemoji'])) {
|
||
$sql = $this->where_limit_emoji($table, $fname, $kw);
|
||
} elseif (!empty($finfo['iswhere'])) {
|
||
$sql = $this->where_limit_eq($table, $fname, $kw);
|
||
} else {
|
||
$sql = $this->_where($table, $fname, $kw, $finfo, true);
|
||
}
|
||
|
||
if ($sql !== null && $sql !== '') {
|
||
$select->where($sql, null, false);
|
||
}
|
||
|
||
return $select;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 日期字符串转时间戳(无时分秒时:开始补 00:00:00,结束补 23:59:59)
|
||
*/
|
||
protected function _limit_date_to_time($date, $is_end = false) {
|
||
|
||
$date = trim((string) $date);
|
||
if ($date === '') {
|
||
return $is_end ? SYS_TIME : 1;
|
||
}
|
||
if (strpos($date, ' ') === false) {
|
||
$date .= $is_end ? ' 23:59:59' : ' 00:00:00';
|
||
}
|
||
|
||
return (int) strtotime($date);
|
||
}
|
||
|
||
/**
|
||
* 条件查询
|
||
*
|
||
* @param object $select 查询对象
|
||
* @param intval $where 是否搜索
|
||
* @return intval
|
||
*/
|
||
protected function _limit_page_where(&$select, $param) {
|
||
|
||
// 默认搜索条件
|
||
$this->param['where_list'] && $select->where($this->param['where_list']);
|
||
|
||
// 默认搜索条件 关联查询
|
||
$this->param['join_list'] && $select->join(
|
||
$this->param['join_list'][0],
|
||
$this->param['join_list'][1],
|
||
$this->param['join_list'][2]
|
||
);
|
||
|
||
// 定义的条件
|
||
if ($this->param['where']) {
|
||
foreach ($this->param['where'] as $v) {
|
||
dr_count($v) == 2 ? $select->where($v[0], $v[1]) : $select->where($v, null, false);
|
||
}
|
||
}
|
||
|
||
// 条件搜索
|
||
if ($param) {
|
||
$field = $this->field;
|
||
$field[$this->id] = $this->id;
|
||
// 关键字 + 自定义字段搜索
|
||
if (isset($param['keyword']) && $param['keyword'] != '') {
|
||
if (isset($this->init['is_swhere']) && $this->init['is_swhere']) {
|
||
if (isset($this->sfield[$param['field']]) && $this->stable) {
|
||
$select = $this->_limit_where($select, $param, $this->sfield, $this->stable);
|
||
} elseif (isset($field[$param['field']])) {
|
||
$select = $this->_limit_where($select, $param, $field, $this->table);
|
||
}
|
||
} else {
|
||
if (isset($field[$param['field']])) {
|
||
$select = $this->_limit_where($select, $param, $field, $this->table);
|
||
} elseif (isset($this->sfield[$param['field']]) && $this->stable) {
|
||
$select = $this->_limit_where($select, $param, $this->sfield, $this->stable);
|
||
}
|
||
}
|
||
}
|
||
// 时间搜索(date_form / date_to → BETWEEN)
|
||
if ($this->date_field) {
|
||
$date_form = isset($param['date_form']) ? trim((string) $param['date_form']) : '';
|
||
$date_to = isset($param['date_to']) ? trim((string) $param['date_to']) : '';
|
||
if ($date_form !== '' || $date_to !== '') {
|
||
if ($date_form !== '') {
|
||
$start = max($this->_limit_date_to_time($date_form, false), 1);
|
||
$end = $date_to !== '' ? $this->_limit_date_to_time($date_to, true) : SYS_TIME;
|
||
} else {
|
||
$start = 1;
|
||
$end = $this->_limit_date_to_time($date_to, true);
|
||
}
|
||
$sql = $this->where_between($this->date_field, $start, $end);
|
||
if ($sql) {
|
||
$select->where($sql, null, false);
|
||
}
|
||
}
|
||
}
|
||
// 栏目查询
|
||
if (isset($param['catid']) && $param['catid'] && function_exists('dr_cat_value')) {
|
||
$mid = defined('MOD_DIR') ? MOD_DIR : (APP_DIR ? APP_DIR : 'share');
|
||
$cat = dr_cat_value($mid, $param['catid']);
|
||
$cat && $cat['child'] ? $select->whereIn('catid', explode(',', $cat['childids'])) : $select->where('catid', (int)$param['catid']);
|
||
}
|
||
// 其他自定义字段查询
|
||
if (isset($this->param['is_diy_where_list']) && $this->param['is_diy_where_list']) {
|
||
$where = [];
|
||
foreach ($param as $i => $v) {
|
||
if (!in_array($i, ['id', 'keyword', 'catid', 'date_form', 'date_to', 'field', 'total']) && isset($field[$i]) && $field[$i]['ismain'] && strlen($v)) {
|
||
$where[] = str_replace('`{finecms_table}`.', '', $this->_where('{finecms_table}', $i, $v, $field));
|
||
}
|
||
}
|
||
$where && $select->where(implode(' AND ', $where), null, false);
|
||
}
|
||
}
|
||
|
||
return $param;
|
||
}
|
||
|
||
// 分页
|
||
public function limit_page($size = SYS_ADMIN_PAGESIZE, $where = '') {
|
||
|
||
$page = max(1, (int)\Phpcmf\Service::L('input')->get('page'));
|
||
$total = (int)\Phpcmf\Service::L('input')->get('total');
|
||
|
||
$param = \Phpcmf\Service::L('input')->get();
|
||
unset($param['s'], $param['c'], $param['m'], $param['d'], $param['page']);
|
||
if (isset($param['keyword']) && $param['keyword']) {
|
||
$param['keyword'] = trim(urldecode($param['keyword']));
|
||
}
|
||
|
||
if ($size > 0 && !$total) {
|
||
$select = $this->db->table($this->table);
|
||
if ($this->param['group_list']) {
|
||
$select->select('count(DISTINCT '.$this->param['group_list'].') as total');
|
||
} else {
|
||
$select->select('count(*) as total');
|
||
}
|
||
// 自定义查询闭包函数
|
||
if (isset($this->init['select_function'])) {
|
||
$this->init['select_function']($select);
|
||
}
|
||
$where && $select->where($where);
|
||
$param = $this->_limit_page_where($select, $param);
|
||
$query = $select->get();
|
||
if (!$query) {
|
||
log_message('debug', '数据查询失败:'.$this->table);
|
||
$this->_clear();
|
||
return [[], $total, $param];
|
||
}
|
||
$data = $query->getRowArray();
|
||
$total = (int)$data['total'];
|
||
$param['total'] = $total;
|
||
unset($select);
|
||
if (!$total) {
|
||
$this->_clear();
|
||
return [[], $total, $param];
|
||
}
|
||
}
|
||
|
||
$select = $this->db->table($this->table);
|
||
$this->param['select_list'] && $select->select($this->param['select_list']);
|
||
// 自定义查询闭包函数
|
||
if (isset($this->init['select_function'])) {
|
||
$this->init['select_function']($select);
|
||
}
|
||
$where && $select->where($where);
|
||
$param = $this->_limit_page_where($select, $param);
|
||
if ($size > 0) {
|
||
$select->limit($size, intval($size * ($page - 1)));
|
||
}
|
||
|
||
$this->param['group_list'] && $select->groupBy($this->param['group_list']);
|
||
|
||
//分析参数合法性
|
||
$order = isset($param['order']) && $param['order'] ? urldecode($param['order']) : ''; // 获取的排序参数
|
||
$order_str = dr_safe_replace($this->param['order_list']);
|
||
if ($order) {
|
||
$arr = explode(',', $order);
|
||
$order_arr = [];
|
||
foreach ($arr as $t) {
|
||
list($order_field, $b) = explode(' ', $t);
|
||
if ($this->is_field_exists($this->table, $order_field)) {
|
||
if ($this->stable && $this->is_field_exists($this->stable, $order_field)) {
|
||
// 两个表都有这个字段
|
||
$order_arr[] = $this->table.'.'.$order_field.' '.($b && $b=='asc' ? 'asc' : 'desc');
|
||
} else {
|
||
$order_arr[] = $order_field.' '.($b && $b=='asc' ? 'asc' : 'desc');
|
||
}
|
||
} elseif ($this->stable && $this->is_field_exists($this->stable, $order_field)) {
|
||
$order_arr[] = $this->stable.'.'.$order_field.' '.($b && $b=='asc' ? 'asc' : 'desc');
|
||
}
|
||
}
|
||
if ($order_arr) {
|
||
$order_str = implode(',', $order_arr);
|
||
}
|
||
}
|
||
$query = $select->orderBy($order_str ? $order_str : 'id desc')->get();
|
||
if (!$query) {
|
||
log_message('debug', '数据查询失败:'.$this->table);
|
||
$this->_clear();
|
||
return [[], $total, $param];
|
||
}
|
||
$data = $query->getResultArray();
|
||
|
||
$param['order'] = $order;
|
||
$param['total'] = $total;
|
||
|
||
// 收尾工作
|
||
$this->_clear();
|
||
|
||
return [$data, $total, $param];
|
||
|
||
}
|
||
|
||
/**
|
||
* 是否含标识符引号字符(` " [)
|
||
*/
|
||
public function has_id_quotes($expr) {
|
||
return (bool) preg_match('/[`"\[]/', (string) $expr);
|
||
}
|
||
|
||
/**
|
||
* 是否已是列表达式(含表.字段 或已加引)
|
||
*/
|
||
public function is_column_expr($expr) {
|
||
$expr = (string) $expr;
|
||
return strpos($expr, '.') !== false || $this->has_id_quotes($expr);
|
||
}
|
||
|
||
/**
|
||
* 去掉标识符外层引号(单段)
|
||
*/
|
||
public function strip_id_quotes($id) {
|
||
return trim(preg_replace('/^[`"\[\]]+|[`"\[\]]+$/', '', (string) $id));
|
||
}
|
||
|
||
/**
|
||
* 去掉表达式中全部标识符引号,保留点号
|
||
*/
|
||
public function unquote_id($expr) {
|
||
return trim(preg_replace('/[`"\[\]]+/', '', (string) $expr));
|
||
}
|
||
|
||
/**
|
||
* 取裸字段名(剥引号后取最后一段,如 `t`.`thumb` → thumb)
|
||
*/
|
||
public function bare_field($expr) {
|
||
|
||
$bare = $this->unquote_id($expr);
|
||
if ($bare === '') {
|
||
return '';
|
||
}
|
||
if (strpos($bare, '.') !== false) {
|
||
$parts = explode('.', $bare);
|
||
return (string) end($parts);
|
||
}
|
||
|
||
return $bare;
|
||
}
|
||
|
||
/**
|
||
* 单段标识符加引(走驱动 escapeIdentifiers)
|
||
*/
|
||
public function quote_id($id) {
|
||
|
||
$id = $this->strip_id_quotes($id);
|
||
if ($id === '') {
|
||
return '';
|
||
}
|
||
if ($this->db && method_exists($this->db, 'escapeIdentifiers')) {
|
||
return $this->db->escapeIdentifiers($id);
|
||
}
|
||
|
||
return '`'.$id.'`';
|
||
}
|
||
|
||
/**
|
||
* 表名加引
|
||
*/
|
||
public function quote_table($table) {
|
||
return $this->quote_id($table);
|
||
}
|
||
|
||
/**
|
||
* 表.字段 加引(table、name 均可为已加引旧串,会先剥再加)
|
||
*/
|
||
public function quote_field($table, $name = '') {
|
||
|
||
if ($name === '' || $name === null) {
|
||
return $this->quote_column($table);
|
||
}
|
||
|
||
return $this->quote_id($table).'.'.$this->quote_id($name);
|
||
}
|
||
|
||
/**
|
||
* 列表达式规范化加引(支持 thumb / table.thumb / `t`.`f` / "t"."f")
|
||
*/
|
||
public function quote_column($expr) {
|
||
|
||
$bare = $this->unquote_id($expr);
|
||
if ($bare === '') {
|
||
return '';
|
||
}
|
||
if (strpos($bare, '.') !== false) {
|
||
$parts = explode('.', $bare);
|
||
$field = array_pop($parts);
|
||
$table = implode('.', $parts);
|
||
|
||
return $this->quote_field($table, $field);
|
||
}
|
||
|
||
return $this->quote_id($bare);
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////
|
||
|
||
/** 字段条件:表列标识(驱动加引) */
|
||
protected function _where_field_col($table, $name) {
|
||
|
||
if ($table === '' || $table === null) {
|
||
return $this->quote_column($name);
|
||
}
|
||
// name 已是完整列表达式时只规范化
|
||
if ($this->is_column_expr($name)) {
|
||
return $this->quote_column($name);
|
||
}
|
||
|
||
return $this->quote_field($table, $name);
|
||
}
|
||
|
||
/** 多条件 OR/AND 合并(value 含 || 时用 AND) */
|
||
protected function _where_field_join($value, array $where, $table) {
|
||
if (!$where) {
|
||
return $this->_where_field_col($table, 'id').' = 0';
|
||
}
|
||
$op = strpos((string) $value, '||') !== false ? ' AND ' : ' OR ';
|
||
return '('.implode($op, $where).')';
|
||
}
|
||
|
||
/**
|
||
* 尝试调用当前数据库驱动的 where 表达式方法
|
||
* @return array{0:bool,1:mixed} [是否已由驱动处理, 驱动返回值]
|
||
*/
|
||
protected function _try_db_where($method, ...$args) {
|
||
|
||
if ($this->db && method_exists($this->db, $method)) {
|
||
return [true, call_user_func_array([$this->db, $method], $args)];
|
||
}
|
||
|
||
return [false, null];
|
||
}
|
||
|
||
/**
|
||
* FIND_IN_SET 表达式(优先驱动 whereFindInSet;默认 MySQL)
|
||
* @param string $column 已带标识符的列,如 `dr_x`.`uid`
|
||
*/
|
||
public function where_find_in_set($column, $value) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFindInSet', (string) $column, $value);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
// 默认 MySQL
|
||
if (dr_is_numeric($value)) {
|
||
return 'FIND_IN_SET('.intval($value).','.(string) $column.')';
|
||
}
|
||
|
||
return 'FIND_IN_SET("'.dr_safe_replace($value).'",'.(string) $column.')';
|
||
}
|
||
|
||
/**
|
||
* BETWEEN 条件(日期时间戳 / 数值区间统一入口;驱动可选实现 whereBetween)
|
||
* @param string $column 已拼好的列名
|
||
* @param float|int $start
|
||
* @param float|int $end
|
||
*/
|
||
public function where_between($column, $start, $end) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereBetween', (string) $column, $start, $end);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$column = (string) $column;
|
||
if ($column === '') {
|
||
return '';
|
||
}
|
||
|
||
return $column.' BETWEEN '.$start.' AND '.$end;
|
||
}
|
||
|
||
/**
|
||
* 不等于(驱动可选 whereNe;默认 !=,避免部分库不支持 <>)
|
||
* @param string $column 已拼好的列名
|
||
* @param mixed $value 比较值;空字符串表示 != ''
|
||
*/
|
||
public function where_ne($column, $value = '') {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereNe', (string) $column, $value);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$column = (string) $column;
|
||
if ($column === '') {
|
||
return '';
|
||
}
|
||
if ($value === '' || $value === null) {
|
||
return $column." != ''";
|
||
}
|
||
if (dr_is_numeric($value)) {
|
||
return $column.' != '.$value;
|
||
}
|
||
|
||
return $column." != '".dr_safe_replace($value)."'";
|
||
}
|
||
|
||
/**
|
||
* LIKE 条件(驱动可选 whereLike)
|
||
* @param string $column 已拼好的列名
|
||
* @param string $keyword 关键词(可不带 %)
|
||
* @param string $side both|left|right|none(none 表示 keyword 已含通配符)
|
||
*/
|
||
public function where_like($column, $keyword, $side = 'both') {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereLike', (string) $column, $keyword, $side);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$column = (string) $column;
|
||
if ($column === '') {
|
||
return '';
|
||
}
|
||
|
||
$kw = trim($this->db->escapeString((string) $keyword, true), '%');
|
||
if ($side === 'right') {
|
||
$pat = $kw.'%';
|
||
} elseif ($side === 'left') {
|
||
$pat = '%'.$kw;
|
||
} elseif ($side === 'none') {
|
||
$pat = $kw;
|
||
} else {
|
||
$pat = '%'.$kw.'%';
|
||
}
|
||
|
||
return $column.' LIKE \''.$pat.'\'';
|
||
}
|
||
|
||
/**
|
||
* IN / NOT IN 表达式(驱动可选 whereInExpr;与链式 where_in 区分)
|
||
* @param string $column 已拼好的列名
|
||
* @param array|string $values 数组或逗号分隔字符串
|
||
* @param bool $not true 为 NOT IN
|
||
*/
|
||
public function where_in_expr($column, $values, $not = false) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereInExpr', (string) $column, $values, $not);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$column = (string) $column;
|
||
if ($column === '') {
|
||
return '';
|
||
}
|
||
if (!is_array($values)) {
|
||
$values = explode(',', (string) $values);
|
||
}
|
||
$str = '';
|
||
foreach ($values as $a) {
|
||
if (is_string($a)) {
|
||
$a = trim($a);
|
||
}
|
||
if ($a === '' || $a === null) {
|
||
continue;
|
||
}
|
||
$str .= dr_is_numeric($a) ? ','.$a : ',\''.dr_safe_replace($a).'\'';
|
||
}
|
||
$str = trim($str, ',');
|
||
if ($str === '') {
|
||
return '';
|
||
}
|
||
|
||
return $column.($not ? ' NOT IN (' : ' IN (').$str.')';
|
||
}
|
||
|
||
/**
|
||
* 大小比较(驱动可选 whereCmp)
|
||
* @param string $column 已拼好的列名
|
||
* @param string $op >|>=|<|<=
|
||
* @param mixed $value 比较值(数值不强转时原样;模板 GT 等传 intval)
|
||
*/
|
||
public function where_cmp($column, $op, $value) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereCmp', (string) $column, $op, $value);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$column = (string) $column;
|
||
$op = (string) $op;
|
||
if ($column === '' || !in_array($op, ['>', '>=', '<', '<='], true)) {
|
||
return '';
|
||
}
|
||
if (dr_is_numeric($value)) {
|
||
return $column.' '.$op.' '.$value;
|
||
}
|
||
|
||
return $column.' '.$op.' \''.dr_safe_replace($value).'\'';
|
||
}
|
||
|
||
// 缩略图 File/thumb(value=1 有图;否则无图;name 可已带表前缀)
|
||
public function where_field_thumb($table, $name, $value) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFieldThumb', $table, $name, $value);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$col = $this->_where_field_col($table, $name);
|
||
if ($value == 1) {
|
||
return $this->where_ne($col, '');
|
||
}
|
||
|
||
return $col." = ''";
|
||
}
|
||
|
||
// 地图范围
|
||
public function where_field_map($table, $name, $value) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFieldMap', $table, $name, $value);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
list($a, $km) = explode('|', $value);
|
||
list($lng, $lat) = explode(',', $a);
|
||
if ($km && $lat && $lng) {
|
||
$squares = dr_square_point($lng, $lat, $km);
|
||
$lat_col = $this->quote_field($table, $name.'_lat');
|
||
$lng_col = $this->quote_field($table, $name.'_lng');
|
||
|
||
return '('.$this->where_between($lat_col, $squares['right-bottom']['lat'], $squares['left-top']['lat'])
|
||
.' AND '.$this->where_between($lng_col, $squares['left-top']['lng'], $squares['right-bottom']['lng']).')';
|
||
}
|
||
|
||
return '1=1';
|
||
}
|
||
|
||
// DIY 字段搜索回调
|
||
public function where_field_diy($table, $name, $value, $field) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFieldDiy', $table, $name, $value, $field);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
return call_user_func(
|
||
'dr_diy_field_'.substr($field['setting']['option']['file'], 0, -4).'_search',
|
||
$table, $name, $value, $field
|
||
);
|
||
}
|
||
|
||
// 联动菜单
|
||
public function where_field_linkage($table, $name, $value, $field, $is_like = false) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFieldLinkage', $table, $name, $value, $field, $is_like);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$arr = explode('|', $value);
|
||
$where = [];
|
||
if ($is_like && $value) {
|
||
$key = \Phpcmf\Service::L('cache')->get_file('key', 'linkage/'.SITE_ID.'_'.$field['setting']['option']['linkage'].'/');
|
||
if ($key) {
|
||
$query = $this->db->table($this->dbprefix('linkage_data_'.$key))->like('name', $value)->get();
|
||
$row = $query ? $query->getRowArray() : null;
|
||
if ($row) {
|
||
$arr[] = $row['cname'];
|
||
}
|
||
}
|
||
}
|
||
$col = $this->_where_field_col($table, $name);
|
||
foreach ($arr as $val) {
|
||
$data = dr_linkage($field['setting']['option']['linkage'], $val);
|
||
if ($data) {
|
||
if ($data['child']) {
|
||
$where[] = $col.' IN ('.$data['childids'].')';
|
||
} else {
|
||
$where[] = $col.'='.intval($data['ii']);
|
||
}
|
||
}
|
||
}
|
||
|
||
return $this->_where_field_join($value, $where, $table);
|
||
}
|
||
|
||
// 联动菜单多选
|
||
public function where_field_linkages($table, $name, $value, $field, $is_like = false) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFieldLinkages', $table, $name, $value, $field, $is_like);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$arr = explode('|', $value);
|
||
$where = [];
|
||
if ($is_like && $value) {
|
||
$key = \Phpcmf\Service::L('cache')->get_file('key', 'linkage/'.SITE_ID.'_'.$field['setting']['option']['linkage'].'/');
|
||
if ($key) {
|
||
$query = $this->db->table($this->dbprefix('linkage_data_'.$key))->like('name', $value)->get();
|
||
$row = $query ? $query->getRowArray() : null;
|
||
if ($row) {
|
||
$arr[] = $row['cname'];
|
||
}
|
||
}
|
||
}
|
||
foreach ($arr as $val) {
|
||
$data = dr_linkage($field['setting']['option']['linkage'], $val);
|
||
if ($data) {
|
||
if ($data['child']) {
|
||
$ids = explode(',', $data['childids']);
|
||
foreach ($ids as $id) {
|
||
if ($id) {
|
||
$where[] = $this->where_json($table, $name, $id);
|
||
}
|
||
}
|
||
} else {
|
||
$where[] = $this->where_json($table, $name, intval($data['ii']));
|
||
}
|
||
}
|
||
}
|
||
|
||
return $this->_where_field_join($value, $where, $table);
|
||
}
|
||
|
||
// 复选 Selects / Checkbox / Cats
|
||
public function where_field_checkbox($table, $name, $value, $field, $is_like = false) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFieldCheckbox', $table, $name, $value, $field, $is_like);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$arr = explode('|', $value);
|
||
$where = [];
|
||
if ($is_like && $value) {
|
||
$option = dr_format_option_array($field['setting']['option']['options']);
|
||
if ($option) {
|
||
$new = [];
|
||
foreach ($option as $k => $v) {
|
||
if (strpos($v, (string) $value) !== false) {
|
||
$new[] = $k;
|
||
}
|
||
}
|
||
if ($new) {
|
||
$arr = $new;
|
||
}
|
||
}
|
||
}
|
||
foreach ($arr as $val) {
|
||
if ($val) {
|
||
$where[] = $this->where_json($table, $name, $this->db->escapeString(dr_safe_replace($val), true));
|
||
}
|
||
}
|
||
|
||
return $this->_where_field_join($value, $where, $table);
|
||
}
|
||
|
||
// Members / Related(FIND_IN_SET)
|
||
public function where_field_members($table, $name, $value) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFieldMembers', $table, $name, $value);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$arr = explode('|', $value);
|
||
$where = [];
|
||
$col = $this->_where_field_col($table, $name);
|
||
foreach ($arr as $val) {
|
||
if ($val === '' || $val === null) {
|
||
continue;
|
||
}
|
||
$where[] = $this->where_find_in_set($col, $val);
|
||
}
|
||
|
||
return $this->_where_field_join($value, $where, $table);
|
||
}
|
||
|
||
// Radio / Select
|
||
public function where_field_select($table, $name, $value, $field, $is_like = false) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFieldSelect', $table, $name, $value, $field, $is_like);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$arr = explode('|', $value);
|
||
if ($is_like && $value) {
|
||
$option = dr_format_option_array($field['setting']['option']['options']);
|
||
if ($option) {
|
||
$new = [];
|
||
foreach ($option as $k => $v) {
|
||
if (strpos($v, $value) !== false) {
|
||
$new[] = $k;
|
||
}
|
||
}
|
||
if ($new) {
|
||
$arr = $new;
|
||
}
|
||
}
|
||
}
|
||
$where = [];
|
||
$col = $this->_where_field_col($table, $name);
|
||
foreach ($arr as $val) {
|
||
if (dr_is_numeric($val)) {
|
||
$where[] = $col.'='.$val;
|
||
} else {
|
||
$where[] = $col.'=\''.dr_safe_replace($val, ['\\', '/']).'\'';
|
||
}
|
||
}
|
||
|
||
return $this->_where_field_join($value, $where, $table);
|
||
}
|
||
|
||
// LIKE / 多关键词
|
||
public function where_field_like($table, $name, $value) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFieldLike', $table, $name, $value);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$col = $this->_where_field_col($table, $name);
|
||
$arr = explode('%', str_replace(' ', '%', $value));
|
||
if (count($arr) == 1) {
|
||
return $this->where_like($col, $value, 'both');
|
||
}
|
||
$wh = [];
|
||
foreach ($arr as $c) {
|
||
$c && $wh[] = $this->where_like($col, $c, 'both');
|
||
}
|
||
|
||
return $wh ? ('('.implode(strpos($value, '%%') !== false ? ' AND ' : ' OR ', $wh).')') : '';
|
||
}
|
||
|
||
// 等值
|
||
public function where_field_eq($table, $name, $value) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereFieldEq', $table, $name, $value);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$col = $this->_where_field_col($table, $name);
|
||
if (dr_is_numeric($value)) {
|
||
return $col.'='.$value;
|
||
}
|
||
|
||
return $col.'=\''.dr_safe_replace($value, ['\\', '/']).'\'';
|
||
}
|
||
|
||
// 列表搜索:按主键 id(单值或 IN)
|
||
public function where_limit_id($table, $name, $keyword) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereLimitId', $table, $name, $keyword);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$ids = [];
|
||
foreach (explode(',', (string) $keyword) as $i) {
|
||
$ids[] = (int) $i;
|
||
}
|
||
$col = $this->_where_field_col($table, $name);
|
||
if (dr_count($ids) == 1) {
|
||
return $col.' = '.(int) $ids[0];
|
||
}
|
||
|
||
return $col.' IN ('.implode(',', array_map('intval', $ids)).')';
|
||
}
|
||
|
||
// 列表搜索:字段 myfunc 自定义
|
||
public function where_limit_myfunc($param, $field) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereLimitMyfunc', $param, $field);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$func = isset($field['myfunc']) ? $field['myfunc'] : '';
|
||
if (!$func) {
|
||
return '';
|
||
}
|
||
if (!function_exists($func)) {
|
||
CI_DEBUG && log_message('debug', '字段myfunc参数中的函数('.$func.')未定义');
|
||
return '';
|
||
}
|
||
$rt = call_user_func_array($func, [$param]);
|
||
|
||
return $rt ? (string) $rt : '';
|
||
}
|
||
|
||
// 列表搜索:Uid / uid(数字按会员 id,否则按用户名查 id)
|
||
public function where_limit_uid($table, $name, $keyword) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereLimitUid', $table, $name, $keyword);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$col = $this->_where_field_col($table, $name);
|
||
$uid = dr_is_numeric($keyword) ? intval($keyword) : 0;
|
||
if ($uid && $this->db->table('member')->where('id', $uid)->countAllResults()) {
|
||
return $col.' = '.$uid;
|
||
}
|
||
|
||
// 用户名模糊 → 先查 id 再 IN(避免子查询方言差异)
|
||
$query = $this->db->table('member')->select('id')->like('username', $keyword)->get();
|
||
$rows = $query ? $query->getResultArray() : [];
|
||
if (!$rows) {
|
||
return '1=0';
|
||
}
|
||
$ids = [];
|
||
foreach ($rows as $r) {
|
||
$ids[] = (int) $r['id'];
|
||
}
|
||
|
||
return $col.' IN ('.implode(',', $ids).')';
|
||
}
|
||
|
||
// 列表搜索:整数
|
||
public function where_limit_int($table, $name, $keyword) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereLimitInt', $table, $name, $keyword);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
return $this->_where_field_col($table, $name).' = '.intval($keyword);
|
||
}
|
||
|
||
// 列表搜索:表情(原文 + unicode 转义)
|
||
public function where_limit_emoji($table, $name, $keyword) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereLimitEmoji', $table, $name, $keyword);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
$col = $this->_where_field_col($table, $name);
|
||
$key = $this->db->escapeString($keyword, true);
|
||
$key2 = $this->db->escapeString(
|
||
str_replace('\u', '\\\\\\\\u', trim(str_replace('\\', '|', json_encode($keyword)), '"')),
|
||
true
|
||
);
|
||
|
||
return '('.$col.' LIKE \'%'.$key.'%\' OR '.$col.' LIKE \'%'.$key2.'%\')';
|
||
}
|
||
|
||
// 列表搜索:准确匹配
|
||
public function where_limit_eq($table, $name, $keyword) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereLimitEq', $table, $name, $keyword);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
return $this->where_field_eq($table, $name, $keyword);
|
||
}
|
||
|
||
// 条件
|
||
public function field($field) {
|
||
return $this->select($field);
|
||
}
|
||
public function select($field) {
|
||
|
||
if (!$field) {
|
||
return $this;
|
||
}
|
||
|
||
$this->param['select'][] = $field;
|
||
|
||
return $this;
|
||
}
|
||
|
||
/**
|
||
* 聚合/混合 SELECT(跨库安全,escape=false 交给驱动拼好引号)
|
||
* 优先驱动 buildSelectAgg;默认 MySQL 反引号
|
||
*/
|
||
public function select_agg($select) {
|
||
|
||
$select = trim((string) $select);
|
||
if ($select === '') {
|
||
return $this;
|
||
}
|
||
|
||
list($ok, $sql) = $this->_try_db_where('buildSelectAgg', $select);
|
||
if ($ok && $sql !== null && $sql !== '') {
|
||
$this->param['select_raw'][] = $sql;
|
||
} else {
|
||
$this->param['select_raw'][] = $this->_build_select_agg_default($select);
|
||
}
|
||
|
||
return $this;
|
||
}
|
||
|
||
/**
|
||
* COUNT 字段(默认 COUNT(*) AS cnt)
|
||
*/
|
||
public function select_count($field = '*', $alias = 'cnt') {
|
||
return $this->_select_func('COUNT', $field, $alias);
|
||
}
|
||
|
||
/**
|
||
* SUM 字段
|
||
*/
|
||
public function select_sum($field, $alias = 'sum') {
|
||
return $this->_select_func('SUM', $field, $alias);
|
||
}
|
||
|
||
/**
|
||
* AVG 字段
|
||
*/
|
||
public function select_avg($field, $alias = 'avg') {
|
||
return $this->_select_func('AVG', $field, $alias);
|
||
}
|
||
|
||
/**
|
||
* MAX 字段
|
||
*/
|
||
public function select_max($field, $alias = 'max') {
|
||
return $this->_select_func('MAX', $field, $alias);
|
||
}
|
||
|
||
/**
|
||
* MIN 字段
|
||
*/
|
||
public function select_min($field, $alias = 'min') {
|
||
return $this->_select_func('MIN', $field, $alias);
|
||
}
|
||
|
||
/**
|
||
* 单个聚合函数 → select_raw
|
||
*/
|
||
protected function _select_func($fn, $field, $alias = '') {
|
||
|
||
$fn = strtoupper(trim((string) $fn));
|
||
$field = trim((string) $field);
|
||
$alias = trim((string) $alias);
|
||
if ($field === '' || !in_array($fn, ['COUNT', 'SUM', 'AVG', 'MAX', 'MIN'], true)) {
|
||
return $this;
|
||
}
|
||
|
||
list($ok, $sql) = $this->_try_db_where('buildSelectFunc', $fn, $field, $alias);
|
||
if ($ok && $sql !== null && $sql !== '') {
|
||
$this->param['select_raw'][] = $sql;
|
||
} else {
|
||
$this->param['select_raw'][] = $this->_build_select_func_default($fn, $field, $alias);
|
||
}
|
||
|
||
return $this;
|
||
}
|
||
|
||
/**
|
||
* 把 select / select_raw 应用到构建器
|
||
*/
|
||
protected function _apply_builder_select($builder) {
|
||
|
||
if (!empty($this->param['select'])) {
|
||
$builder->select(implode(',', $this->param['select']));
|
||
}
|
||
if (!empty($this->param['select_raw'])) {
|
||
foreach ($this->param['select_raw'] as $raw) {
|
||
if ($raw !== '' && $raw !== null) {
|
||
$builder->select($raw, false);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 默认(MySQL)聚合 SELECT 片段
|
||
*/
|
||
protected function _build_select_agg_default($select) {
|
||
|
||
$parts = $this->_split_select_parts($select);
|
||
$out = [];
|
||
foreach ($parts as $part) {
|
||
$part = trim($part);
|
||
if ($part === '') {
|
||
continue;
|
||
}
|
||
if (preg_match('/^(COUNT|SUM|AVG|MAX|MIN)\s*\(\s*(.+?)\s*\)\s*(?:AS\s+([`"]?[\w]+[`"]?))?\s*$/i', $part, $m)) {
|
||
$out[] = $this->_build_select_func_default(strtoupper($m[1]), trim($m[2]), isset($m[3]) ? trim($m[3], '`"[]') : '');
|
||
continue;
|
||
}
|
||
if (preg_match('/^(.+?)\s+AS\s+([`"]?[\w]+[`"]?)\s*$/i', $part, $m)) {
|
||
$out[] = $this->_quote_select_ident(trim($m[1])).' AS '.$this->quote_id(trim($m[2], '`"[]'));
|
||
continue;
|
||
}
|
||
$out[] = $this->_quote_select_ident($part);
|
||
}
|
||
|
||
return implode(', ', $out);
|
||
}
|
||
|
||
/**
|
||
* 默认(MySQL)单个聚合函数
|
||
*/
|
||
protected function _build_select_func_default($fn, $field, $alias = '') {
|
||
|
||
$fn = strtoupper((string) $fn);
|
||
$inner = (trim($field) === '*') ? '*' : $this->_quote_select_ident($field);
|
||
$sql = $fn.'('.$inner.')';
|
||
$alias = trim((string) $alias, '`"[]');
|
||
if ($alias !== '') {
|
||
$sql .= ' AS '.$this->quote_id($alias);
|
||
}
|
||
|
||
return $sql;
|
||
}
|
||
|
||
/**
|
||
* 列标识加引(支持 table.field / *)
|
||
*/
|
||
protected function _quote_select_ident($expr) {
|
||
|
||
$expr = trim((string) $expr);
|
||
if ($expr === '' || $expr === '*') {
|
||
return $expr === '*' ? '*' : '';
|
||
}
|
||
// 已是函数或复杂表达式:原样返回(调用方应走 select_agg 解析)
|
||
if (preg_match('/[()\s]/', $expr) && !preg_match('/^[\w.`"\[\]]+$/u', $expr)) {
|
||
return $expr;
|
||
}
|
||
|
||
return $this->quote_column($expr);
|
||
}
|
||
|
||
/**
|
||
* 按逗号拆 SELECT 列表(忽略括号内逗号)
|
||
*/
|
||
protected function _split_select_parts($select) {
|
||
|
||
$parts = [];
|
||
$buf = '';
|
||
$depth = 0;
|
||
$len = strlen($select);
|
||
$quote = null;
|
||
for ($i = 0; $i < $len; $i++) {
|
||
$ch = $select[$i];
|
||
if ($quote !== null) {
|
||
$buf .= $ch;
|
||
if ($ch === $quote) {
|
||
if (($ch === "'" || $ch === '"') && $i + 1 < $len && $select[$i + 1] === $ch) {
|
||
$buf .= $select[++$i];
|
||
continue;
|
||
}
|
||
$quote = null;
|
||
}
|
||
continue;
|
||
}
|
||
if ($ch === "'" || $ch === '"' || $ch === '`') {
|
||
$quote = $ch;
|
||
$buf .= $ch;
|
||
continue;
|
||
}
|
||
if ($ch === '(') {
|
||
$depth++;
|
||
$buf .= $ch;
|
||
continue;
|
||
}
|
||
if ($ch === ')') {
|
||
$depth = max(0, $depth - 1);
|
||
$buf .= $ch;
|
||
continue;
|
||
}
|
||
if ($ch === ',' && $depth === 0) {
|
||
$parts[] = $buf;
|
||
$buf = '';
|
||
continue;
|
||
}
|
||
$buf .= $ch;
|
||
}
|
||
if (trim($buf) !== '') {
|
||
$parts[] = $buf;
|
||
}
|
||
|
||
return $parts;
|
||
}
|
||
|
||
// 条件
|
||
public function where($name, $value = '') {
|
||
|
||
if (!$name) {
|
||
return $this;
|
||
}
|
||
|
||
if (is_array($name)) {
|
||
foreach ($name as $f => $v) {
|
||
$this->param['where'][] = !dr_is_numeric($f) ? [$f, $v] : $v;
|
||
}
|
||
} else {
|
||
$this->param['where'][] = dr_strlen($value) ? [$name, $value] : $name;
|
||
}
|
||
|
||
return $this;
|
||
}
|
||
|
||
// 条件
|
||
public function like($name, $value = '') {
|
||
|
||
if (!$name) {
|
||
return $this;
|
||
}
|
||
|
||
if (method_exists($this->db, 'whereLike')) {
|
||
$this->param['where'][] = $this->db->whereLike($name, $value);
|
||
} else {
|
||
$this->param['where'][] = $name.' LIKE "%'.$value.'%"';
|
||
}
|
||
|
||
return $this;
|
||
}
|
||
|
||
// json(优先驱动 whereJson;默认 MySQL)
|
||
public function where_json($table, $name, $value) {
|
||
|
||
list($ok, $sql) = $this->_try_db_where('whereJson', $table, $name, $value);
|
||
if ($ok) {
|
||
return $sql;
|
||
}
|
||
|
||
if ($this->is_column_expr($name)) {
|
||
$name = $this->quote_column($name);
|
||
} else {
|
||
$name = $table ? $this->quote_field($table, $name) : $this->quote_id($name);
|
||
}
|
||
|
||
if (version_compare($this->db->getVersion(), '5.7.0') < 0) {
|
||
return $name.' LIKE \'%"'.$value.'"%\'';
|
||
}
|
||
|
||
return "(CASE WHEN JSON_VALID({$name}) THEN JSON_CONTAINS ({$name}->'$[*]', '\"".$value."\"', '$') ELSE null END)";
|
||
}
|
||
|
||
// in条件
|
||
public function where_in($name, $value) {
|
||
|
||
if (!$name) {
|
||
return $this;
|
||
}
|
||
|
||
if (is_array($value) && $value) {
|
||
$this->param['where_in'][] = [$name, $value];
|
||
}
|
||
|
||
return $this;
|
||
}
|
||
|
||
public function where_date($name, $value) {
|
||
|
||
if (!$name) {
|
||
return $this;
|
||
}
|
||
|
||
//$where = 'DATEDIFF(from_unixtime('.$name.'),now())='.$value;
|
||
$where = '';
|
||
if (!$value) {
|
||
// 今天
|
||
$stime = strtotime(date('Y-m-d', SYS_TIME).' 00:00:00');
|
||
$etime = strtotime(date('Y-m-d 23:59:59', $stime));
|
||
$where = $name." BETWEEN ".$stime." AND ".$etime;
|
||
}
|
||
|
||
$this->param['where'][] = $where;
|
||
|
||
return $this;
|
||
}
|
||
|
||
/**
|
||
* 指定查询数量
|
||
* @access public
|
||
* @param int $offset 起始位置
|
||
* @param int $length 查询数量
|
||
* @return $this
|
||
*/
|
||
public function limit($offset, $length = 0) {
|
||
|
||
$this->param['limit'] = $offset . ($length ? ',' . $length : '');
|
||
|
||
return $this;
|
||
}
|
||
|
||
// 排序
|
||
public function order_by($value, $value2 = null) {
|
||
|
||
$this->param['order'] = $value2 ? $value.' '.$value2 : $value;
|
||
|
||
return $this;
|
||
}
|
||
|
||
public function group_by($value) {
|
||
|
||
$this->param['group'] = $value;
|
||
|
||
return $this;
|
||
}
|
||
|
||
// 运行SQL
|
||
public function query_sql($sql, $more = 0) {
|
||
|
||
$sql = str_replace('{dbprefix}', $this->prefix, $sql);
|
||
$query = $this->db->query($sql);
|
||
if (!$query || !is_object($query)) {
|
||
$this->_clear();
|
||
return [];
|
||
}
|
||
|
||
$rt = $more ? $query->getResultArray() : $query->getRowArray();
|
||
$this->_clear();
|
||
|
||
return $rt;
|
||
}
|
||
|
||
// 批量执行(插件 Install/Uninstall.sql 等)
|
||
// 经 dr_format_create_sql → 驱动 formatCreateSql 做方言转换
|
||
public function query_all($sql, $replace = []) {
|
||
|
||
if (!$sql) {
|
||
$this->_clear();
|
||
return '';
|
||
}
|
||
|
||
$rt = $this->_query_batch($sql, $replace);
|
||
$this->_clear();
|
||
|
||
return $rt['code'] ? '' : $rt['msg'];
|
||
}
|
||
|
||
/**
|
||
* 批量执行 SQL(按分号拆分),成功返回 dr_return_data(1, …)
|
||
*
|
||
* @param string $sql
|
||
* @param array $replace [0=>搜索, 1=>替换],默认含 {dbprefix}
|
||
* @return array
|
||
*/
|
||
public function _query_batch($sql, $replace = []) {
|
||
|
||
if (!isset($replace[0]) || !is_array($replace[0])) {
|
||
$replace[0] = [];
|
||
}
|
||
if (!isset($replace[1]) || !is_array($replace[1])) {
|
||
$replace[1] = [];
|
||
}
|
||
$replace[0][] = '{dbprefix}';
|
||
$replace[1][] = $this->db->DBPrefix;
|
||
|
||
$todo = [];
|
||
$count = 0;
|
||
$sql_data = explode(';SQL_FINECMS_EOL', trim(str_replace([PHP_EOL, chr(13), chr(10)], 'SQL_FINECMS_EOL', str_replace($replace[0], $replace[1], $sql))));
|
||
if ($sql_data) {
|
||
foreach ($sql_data as $query) {
|
||
if (!$query) {
|
||
continue;
|
||
}
|
||
$ret = '';
|
||
$queries = explode('SQL_FINECMS_EOL', trim($query));
|
||
foreach ($queries as $query) {
|
||
$ret .= $query[0] == '#' || $query[0].$query[1] == '--' ? '' : $query;
|
||
}
|
||
$ret = trim($ret);
|
||
if (!$ret) {
|
||
continue;
|
||
}
|
||
if ($this->db->simpleQuery(dr_format_create_sql($ret))) {
|
||
$todo[] = $ret;
|
||
$count++;
|
||
} else {
|
||
$err = $this->db->error();
|
||
return dr_return_data(0, ($err['message'] ?? '').'<br> '.$ret);
|
||
}
|
||
}
|
||
}
|
||
|
||
return dr_return_data(1, '', [$count, $todo]);
|
||
}
|
||
|
||
// 获取当前执行后的sql语句
|
||
public function get_sql_query() {
|
||
|
||
if (!$this->db) {
|
||
return '';
|
||
} elseif (!method_exists($this->db, 'getLastQuery')) {
|
||
return '';
|
||
}
|
||
|
||
$my = $this->db->getLastQuery();
|
||
if (!$my) {
|
||
$this->_clear();
|
||
return '';
|
||
}
|
||
|
||
if ($my && !method_exists($my, 'getQuery')) {
|
||
$this->_clear();
|
||
return (string)$my;
|
||
}
|
||
|
||
$rt = str_replace(PHP_EOL, ' ', $my->getQuery());
|
||
$this->_clear();
|
||
|
||
return $rt;
|
||
}
|
||
|
||
// 关闭数据库
|
||
public function close() {
|
||
if (method_exists($this->db, 'close')) {
|
||
$this->db->close();
|
||
}
|
||
}
|
||
|
||
private function _clear() {
|
||
$this->key = $this->id;
|
||
$this->date_field = 'inputtime';
|
||
$this->field = [];
|
||
$this->param = [];
|
||
if ($this->db_temp) {
|
||
// 还原默认库
|
||
$this->db = $this->db_temp;
|
||
$this->prefix = $this->db_temp->DBPrefix;
|
||
$this->db_temp = NULL;
|
||
}
|
||
}
|
||
|
||
// 附表分表规则
|
||
public function get_table_id($id) {
|
||
return floor($id / 100000);
|
||
}
|
||
|
||
// 显示数据库错误
|
||
private function _return_error($msg) {
|
||
return IS_ADMIN || IS_DEV ? dr_return_data(0, $msg) : dr_return_data(0, dr_lang('系统错误'));
|
||
}
|
||
}
|