123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- <?php namespace Maze\Data;
- use Maze\Debug\Process as Debug;
- use Maze\Config\Load as Config;
- use Maze\Http\Output;
- use Maze\Http\Input;
- use Maze\Routing\Load;
- class Model
- {
- /**
- * database
- *
- * @var array
- */
- protected $database;
- /**
- * config
- *
- * @var array
- */
- protected $config;
- /**
- * db
- *
- * @var Object
- */
- protected $db;
- /**
- * __construct
- *
- * @return mixd
- */
- public function __construct($config)
- {
- $this->config =& $config;
- $this->database = Config::get('database', $config['project']);
- }
- /**
- * db
- *
- * @return mixd
- */
- protected function db($key = '')
- {
- if(!$key)
- {
- $key = isset($this->config['project']) ? $this->config['project'] : MAZE_PROJECT_NAME;
- }
- if(empty($this->database[$key]))
- {
- if(empty($this->database['default']))
- {
- Output::abert('core_database_exists', $key);
- }
- $this->database[$key] = $this->database['default'];
- }
- if(empty($this->db[$key]))
- {
- //$this->config['name'] = $key . '_' . $this->config['name'];
-
- $method = 'Maze\\Data\\' . ucwords($this->database[$key]['type']) . '\\Store';
- $this->db[$key] = new $method($this->database[$key]);
- $this->db[$key]->table($key . '_' . $this->config['name']);
- # 建表
- if(isset($this->config['struct']))
- {
- $create = $this->db[$key]->create($this->config['struct']);
- if($create === true)
- {
- # 写入默认值
- if(isset($this->config['default']))
- {
- $this->db[$key]->inserts($this->config['default']);
- }
- }
- else
- {
- if(isset($create['struct']))
- {
- if(count($create['struct']) < count($this->config['struct']))
- {
- $alter = array_diff_key($this->config['struct'], $create['struct']);
- if($alter)
- {
- $this->db[$key]->alter($alter, $this->config['struct']);
- }
- }
- }
-
- # 更改表结构
- if(isset($this->config['alter']))
- {
- $this->db[$key]->alter($this->config['alter']);
- }
- }
- # 建立索引
- if(isset($this->config['index']))
- {
- $this->db[$key]->index($this->config['index']);
- }
- }
- }
- return $this->db[$key];
- }
-
- /**
- * 获取匹配的类型
- *
- * @return mixd
- */
- private function type($method)
- {
- switch($method)
- {
- case 1:
- $method = '=';
- break;
- case 2:
- $method = 'like';
- break;
- case 3:
- $method = '>';
- break;
- case 4:
- $method = '>=';
- break;
- case 5:
- $method = '<';
- break;
- case 6:
- $method = '<=';
- break;
- }
-
- return $method;
- }
-
- /**
- * # 初始化默认方法one、list、update、insert、delete
- *
- * @return mixd
- */
- private function init($method, $param = array())
- {
- $array = array();
- $type = '';
-
- $this->config['request'][$method] = array
- (
- 'type' => $method,
- 'where' => array('id' => 'yes'),
- );
-
- # 支持单独字段更新
- $key = '';
- if(strpos($method, 'update_') !== false)
- {
- $key = str_replace('update_', '', $method);
- if($key && isset($this->config['struct'][$key]))
- {
- $match = $this->config['struct'][$key]['match'];
- if(is_array($this->config['struct'][$key]['match']))
- {
- $match = $this->config['struct'][$key]['match'][0];
- }
- $this->config['request'][$method]['type'] = 'update';
- $this->config['request'][$method]['set'][$key] = $match;
- $this->config['request'][$method]['where']['id'] = 'yes';
- return;
- }
- }
- switch($method)
- {
- case 'one':
- case 'delete':
- break;
- case 'updatemul':
- #批量更新操作,仅仅开启了mul_type配置或者后台可用
- if(isset(Config::$global['base']['mul_type']) && Config::$global['base']['mul_type'] > 0)
- {
- $this->config['request'][$method]['type'] = 'update';
- if(Config::$global['base']['mul_type'] == 2)
- {
- unset($this->config['request'][$method]['where']);
- $type = 'option';
- }
- else
- {
- $type = 'mul';
- $this->config['request'][$method]['where']['id'] = array('yes', 'in');
- }
- }
- break;
- case 'update':
- $type = 'set';
- break;
- case 'insert':
- unset($this->config['request'][$method]['where']);
- $type = 'add';
- break;
- case 'state':
- $this->config['request']['state'] = array
- (
- 'type' => 'one',
- 'where' => array
- (
- 'state' => 1,
- 'id' => 'yes'
- )
- );
- break;
- case 'list':
- $type = 'option';
- $this->config['request']['list'] = array
- (
- 'type' => 'all',
- 'order' => array('id', 'desc'),
- 'page' => array(15, 'list'),
- 'col' => '*|id',
- 'option' => array(),
- );
-
- if(isset($this->config['manage']['list_type']) && $this->config['manage']['list_type'] == 'parent')
- {
- $this->config['request']['list']['page'][0] = 500;
- }
-
- if(isset(Config::$global['base']['excel']))
- {
- unset($this->config['request']['list']['page']);
- }
- break;
- case 'total':
- $type = 'option';
- $this->config['request']['total'] = array
- (
- 'type' => 'all',
- 'col' => 'count(*) as total',
- 'group' => array('month'),
- 'option' => array(),
- );
- break;
- default:
- unset($this->config['request'][$method]);
- break;
- }
- if($type)
- {
- if($type == 'option')
- {
- $param['search_type'] = isset($param['search_type']) ? $param['search_type'] : Input::get('search_fulltext_type', 1);
-
- $param['search_type'] = $this->type($param['search_type']);
- }
- foreach($this->config['struct'] as $k => $v)
- {
- if(isset($v['match']))
- {
- # 这里增加value,用以区分update/select的值
- if(is_array($v['match']))
- {
- $v['value'] = $v['match'][1];
- $v['match'] = $v['match'][0];
- }
- else
- {
- $v['value'] = $v['match'];
- }
-
- # 首先匹配批量更新
- if($method == 'updatemul' && isset($v['update']) && $v['update'] == 'radio' && (is_array($v['option']) || is_object($v['option'])))
- {
- $this->config['request'][$method]['set'][$k] = $v['value'];
- }
- if($type == 'option')
- {
- # 位运算
- if(isset($v['bit']))
- {
- $this->config['request'][$method][$type][$k] = array('option', '&');
- }
- # 默认排序
- elseif(isset($v['order']))
- {
- if(isset($this->config['request'][$method]['order']))
- {
- if($this->config['request'][$method]['order'][0] && $this->config['request'][$method]['order'][0] != $k)
- {
- $this->config['request'][$method]['order'][0] = $k . '` '.(is_string($v['order']) ? $v['order'] : 'desc').',`' . $this->config['request'][$method]['order'][0];
- }
- }
- }
- # 全文检索
- if(isset($v['search']) && strpos($v['search'], 'fulltext') !== false)
- {
- $this->config['request'][$method][$type][$k] = array('option', $param['search_type']);
- }
- # 时间区间
- elseif(isset($v['search']) && (strpos($v['search'], 'time') !== false || strpos($v['search'], 'date') !== false))
- {
- $this->config['request'][$method][$type]['start_' . $k] = array('yes-' . $k, '>=');
- $this->config['request'][$method][$type]['end_' . $k] = array('yes-' . $k, '<=');
- }
- else
- {
- $this->config['request'][$method][$type][$k] = $v['match'];
- }
- }
- elseif($type != 'mul' && !isset($v['table']))
- {
- if(!empty($v['insert']) && $type == 'set')
- {
-
- }
- else
- {
- $this->config['request'][$method][$type][$k] = $v['value'];
- }
- }
- }
- }
- }
-
- //print_r($_POST);die;
- //print_r($this->config['request'][$method]);die;
- }
- /**
- * method
- *
- * @return mixd
- */
- public function method($method = 'one', $param = array())
- {
- if(isset($param[0]) && is_array($param[0]))
- {
- $result = array();
- foreach($param as $k => $v)
- {
- $result[] = $this->method($method, $v);
- }
-
- return $result;
- }
- if(!isset($this->config['request'][$method])) $this->init($method, $param);
-
- //print_r($this->config['request']);die;
-
- $this->config['param'] = array();
- if(isset($this->config['request']) && isset($this->config['request'][$method]))
- {
- $this->hack('request', 'onload');
- $this->hack($method, 'start');
-
- # 验证头部权限
- if(isset($this->config['auth']) && is_string($this->config['auth']))
- {
- $value = isset($param[$this->config['auth_key']]) ? $param[$this->config['auth_key']] : Input::get($this->config['auth_key']);
- if($value)
- {
- $top['value'] = $value;
- }
- else
- {
- $top = Load::get('manage/auth.getTop', array($this->config['auth']));
- }
- if($top)
- {
- if(!Input::get('where_' . $this->config['auth_key'])) Input::set('where_' . $this->config['auth_key'], $top['value']);
- if(!Input::get('option_' . $this->config['auth_key'])) Input::set('option_' . $this->config['auth_key'], $top['value']);
- if(!Input::get('set_' . $this->config['auth_key'])) Input::set('set_' . $this->config['auth_key'], $top['value']);
- if(!Input::get('add_' . $this->config['auth_key'])) Input::set('add_' . $this->config['auth_key'], $top['value']);
- }
- }
- if($param)
- {
- if(!is_array($param))
- {
- $param = array('where_id' => $param);
- }
- elseif(is_array($param) && isset($top))
- {
- if(!isset($param['where_' . $this->config['auth_key']])) $param['where_' . $this->config['auth_key']] = $top['value'];
- if(!isset($param['option_' . $this->config['auth_key']])) $param['option_' . $this->config['auth_key']] = $top['value'];
- if(!isset($param['set_' . $this->config['auth_key']])) $param['set_' . $this->config['auth_key']] = $top['value'];
- if(!isset($param['add_' . $this->config['auth_key']])) $param['add_' . $this->config['auth_key']] = $top['value'];
- }
- $this->config['param'] =& $param;
- }
-
- # 创建全局参数,给hack使用
- Config::$global['base']['_param'] = $this->config['param'];
-
- $this->config['response'] = $this->config['request'][$method];
- $this->push(array('where', 'add', 'set', 'option'))->condition(array('page', 'order', 'limit', 'group'));
- $type = isset($this->config['response']['type']) ? $this->config['response']['type'] : $method;
- $this->config['response']['col'] = isset($this->config['response']['col']) ? $this->config['response']['col'] : '';
- $data = $this->db()->$type($this->config['response']['col']);
-
- $this->hack($method, 'end', $data);
-
- return $data;
- }
- return array();
- }
- /**
- * hack 插件钩子处理
- * @param string $key
- *
- * @return mixd
- */
- private function hack($key, $method = 'start', $param = false)
- {
- # 不再继续执行hack,就设置这个参数
- if(Input::get('maze_onload') == 'no')
- {
- if($method == 'end')
- {
- Input::set('maze_onload', 'yes');
- }
- }
- elseif(isset($this->config[$method][$key]))
- {
- # 如果定义了auth,就要传过去
- if(isset($this->config['auth']) && is_array($this->config['auth']))
- {
- $param = array($param, $this->config['auth']);
- }
- if(is_array($this->config[$method][$key]))
- {
- foreach($this->config[$method][$key] as $k => $v)
- {
- Load::get($v, $param);
- }
- }
- else
- {
- Load::get($this->config[$method][$key], $param);
- }
- }
- }
- /**
- * push
- *
- * @return mixd
- */
- private function push($param)
- {
- foreach($param as $k => $v)
- {
- if(isset($this->config['response'][$v]))
- {
- # 验证传入参数与配置是否相同
- /*
- $request = Input::prefix($v . '_');
- if($v == 'where')
- {
- $request = Input::prefix('where_');
- }
- */
-
- $value = array();
- foreach($this->config['response'][$v] as $i => $j)
- {
- $t = array();
- if(is_array($j))
- {
- $t = $j;
- $j = $t[0];
- }
- $temp = $this->request($v. '_' . $i, $j, '', $i, $v);
- //if($temp || (($v == 'add' || $v == 'set') && $temp && $temp == 0))
- if($temp || (($v == 'add' || $v == 'set') && ($temp === '0' || $temp === 0)))
- //if($temp)
- {
- if(is_array($temp))
- {
- if(isset($this->config['struct'][$i]) && isset($this->config['struct'][$i]['bit']))
- {
- $vt = 0;
- foreach($temp as $ki => $vi)
- {
- if(isset($this->config['struct'][$i]['bit'][$vi]))
- {
- $vt += $this->config['struct'][$i]['bit'][$vi];
- }
- }
- $temp = $vt;
- }
- elseif(isset($temp[0]) && is_array($temp[0]))
- {
- $temp = base64_encode(json_encode($temp));
- }
- else
- {
- $temp = implode(',', $temp);
- }
- }
-
- if($temp == 'null')
- {
- $temp = '';
- }
- $g = array($i, $temp);
- if(isset($t[1]))
- {
- $g[2] = $t[1];
- }
- if(isset($t[2]))
- {
- $g[3] = $t[2];
- }
- $value[] = $g;
- }
- }
- if($value)
- {
- if($v == 'option')
- {
- $v = 'where';
- }
- $this->db()->$v($value);
- }
- }
- }
- return $this;
- }
- /**
- * condition
- *
- * @return mixd
- */
- private function condition($param)
- {
- foreach($param as $k => $v)
- {
- if(isset($this->config['response'][$v]))
- {
- if($v == 'page')
- {
- $value = $this->config['response'][$v];
- if(is_string($value[1]))
- {
- $temp[] = $value[1];
- unset($value[1]);
- $value[1] = $temp;
- }
- if(isset($value[2])) $value[1][2] = $value[2];
- if(isset($this->config['param']['page']))
- {
- $value[1] = array_merge($value[1], $this->config['param']['page']);
- }
- }
- else
- {
- $temp = '';
- $value = $this->request($v, $this->config['response'][$v], '-', $temp);
- if(!$value)
- {
- $value = $this->config['response'][$v];
- }
- }
- if(is_string($value))
- {
- $value = array($value, '');
- }
- if(empty($value[1])) $value[1] = '';
- $this->db()->$v($value[0], $value[1]);
- }
- }
- return $this;
- }
- /**
- * request
- *
- * @return mixd
- */
- private function request($key, $value, $split = '', &$index, $method = '')
- {
- //$index = str_replace(array('add_', 'where_', 'set_', 'option_'), '', $key);
-
- if($index && strpos($value, 'yes-') !== false)
- {
- $temp = explode('-', $value);
- $value = $temp[0];
- $index = $temp[1];
- }
-
- if($index && $value == 'yes' && isset($this->config['struct'][$index]) && is_array($this->config['struct'][$index]) && isset($this->config['struct'][$index]['match']) && $this->config['struct'][$index]['match'])
- {
- if(is_array($this->config['struct'][$index]['match']))
- {
- $value = $this->config['struct'][$index]['match'][0];
- }
- else
- {
- $value = $this->config['struct'][$index]['match'];
- }
- }
- $state = false;
-
- if(isset($this->config['param'][$key]))
- {
- $request = $this->config['param'][$key];
- }
- if($value == 'option')
- {
- $value = '';
- $state = true;
- }
- $callback = is_string($value) && function_exists($value);
- if($callback)
- {
- $callback = $value;
- $value = '';
- }
-
- if(empty($request))
- {
- if(isset($request) && $request == 0)
- {
- return $request;
- }
- $request = Input::get($key, $value);
- }
-
- if(($method == 'set' || $method == 'add') && empty($request) && isset($this->config['struct'][$index]['default']) && $this->config['struct'][$index]['default'])
- {
- //$request = $this->config['struct'][$index]['default'];
- }
- /*
- if(is_array($request))
- {
- $request = implode(',', $request);
- }
- */
- if(is_string($value) && strpos($value, '/') !== false)
- {
- $state = preg_match($value, $request);
- }
- elseif(!empty($request))
- {
- if($callback)
- {
- $state = $callback($request);
- }
- elseif(is_string($request) && $split && strpos($request, $split) !== false)
- {
- $request = explode($split, $request);
- }
- $state = true;
- }
- //Debug::log(array('text' => 'model', 'state' => $state, 'preg' => $value, 'key' => $key, 'value' => $request));
- if($state)
- {
- if($index && isset($this->config['struct'][$index]) && is_array($this->config['struct'][$index]) && isset($this->config['struct'][$index]['callback']) && $this->config['struct'][$index]['callback'] && $request)
- {
- $call = $this->config['struct'][$index]['callback'];
- if($call == 'maketime')
- {
- if(is_string($request))
- {
- $request = \Maze::maketime($request);
- }
- }
- else
- {
- $request = $call($request);
- }
- }
- return $request;
- }
- # error
- if($method != 'option' && $method != 'add' && $method != 'set')
- {
- if(isset($this->config['struct'][$index]['desc']) && $this->config['struct'][$index]['desc'])
- {
- Output::abert($this->config['struct'][$index]['desc']);
- }
- else
- {
- Output::abert('core_database_request', array($key, ($value ? $value : $callback)));
- }
- }
- return false;
- }
- }
|