From 975e5c0b15ee4f3527f1b388bc386797fa96229d Mon Sep 17 00:00:00 2001 From: hisune Date: Tue, 23 Jun 2015 20:39:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5model=E5=92=8Ctheme=E7=9A=84m?= =?UTF-8?q?ongodb=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 加入model和theme的mongodb支持 --- Tiny/Auth.php | 9 +- Tiny/Controller.php | 43 ++---- Tiny/Helper.php | 26 ++++ Tiny/Mongo.php | 164 ++++++++++++++++++++++ Tiny/ORM.php | 1 + Tiny/Theme/DataTables.php | 278 +++++++++++++++++++++++++++++--------- Tiny/Theme/Mod.php | 99 +++++++++++--- 7 files changed, 494 insertions(+), 126 deletions(-) create mode 100644 Tiny/Mongo.php diff --git a/Tiny/Auth.php b/Tiny/Auth.php index 83ef37e..28a17bb 100644 --- a/Tiny/Auth.php +++ b/Tiny/Auth.php @@ -94,7 +94,7 @@ public static function getPurviewCache() public static function hasPurview($controller = null, $method = null) { if($controller && $method){ - $ctr = ucfirst(Config::$application) . '\\' . Config::$controller['0'] . '\\' . $controller; + $ctr = ucfirst(Config::$application) . '\\' . Config::$controller['0'] . '\\' . ucfirst($controller); }else{ $ctr = Request::$controller; $explode = explode('\\', $ctr); @@ -109,11 +109,10 @@ public static function hasPurview($controller = null, $method = null) $purview = self::getPurviewCache(); $white = property_exists($ctr, 'authWhite') && isset($ctr::$authWhite['purview']) ? $ctr::$authWhite['purview'] : array(); - if( - !in_array($method, $white) && - !in_array($controller . '@' . $method, $purview) && - !in_array($controller . '@*', $purview) + !in_array(strtolower($method), $white) && + !in_array(strtolower($controller . '@' . $method), $purview) && + !in_array(strtolower($controller . '@*'), $purview) ){ return false; } diff --git a/Tiny/Controller.php b/Tiny/Controller.php index 90cfa0b..56f7d0c 100644 --- a/Tiny/Controller.php +++ b/Tiny/Controller.php @@ -28,7 +28,7 @@ public function __call($method, $args) switch($this->{$action}['type']){ case 'theme': $theme = '\\Tiny\\Theme\\' . $this->{$action}['name']; - $setting = lcfirst($method) . $this->{$action}['name'] . 'Setting'; + $setting = $this->_themeSetting($method, $action); $option = isset($this->{$action}['option']) ? $this->{$action}['option'] : array(); $builder = new $theme(lcfirst($method), $option); @@ -44,45 +44,13 @@ public function __call($method, $args) switch($this->{$action}['name']){ case 'Delete': // 删除 - if(Request::get('id')){ - if($model->delete(Request::get('id'))){ + if(Request::get($model->key)){ + if($model->delete(Request::get($model->key))){ Error::echoJson(1); } } Error::echoJson(-1); break; - case 'Mod': // 添加修改 - if(Request::isPost()){ - $post = Request::post(); - if($post){ - // save前置函数,用来改变post值 - $before = lcfirst($method) . 'ModBefore'; - if(method_exists($helper, $before)){ - $helper::$before($post); - } - $attribute = array_keys($model::attributes()); - foreach($post as $k => $v){ - if(in_array($k, $attribute)){ - if(is_array($v)) $v = json_encode($v); - $model->$k = $v; - } - } - - if(isset($model->_data[$model->key]) && $model->_data[$model->key]){ - $result = $model->update(); - }else{ - $result = $model->save(); - } - if($result) - Error::echoJson('1', 'success'); - else - Error::echoJson('1', 'save error'); - }else - Error::echoJson('-1', 'data error'); - }else{ - Error::echoJson('-1', 'method error'); - } - break; } break; default: @@ -113,6 +81,11 @@ public function __get($name) } } + private function _themeSetting($method, $action) + { + return lcfirst($method) . $this->{$action}['name'] . 'Setting'; + } + /** * Called before the controller method is run */ diff --git a/Tiny/Helper.php b/Tiny/Helper.php index aee829e..d9b8530 100644 --- a/Tiny/Helper.php +++ b/Tiny/Helper.php @@ -15,6 +15,7 @@ public static function renderEnum(array $data, $key = 'id', $value = null) if ($data) { foreach ($data as $v) { if(is_object($v)) $v = (array)$v; + if(is_object($v[$key])) $v[$key] = strval($v[$key]); if(is_string($value)) $option[$v[$key]] = $v[$value]; else{ @@ -72,4 +73,29 @@ public static function getHumanTree(array $tree = [], $level = 0, $child = 'chil return $array; } + public static function mongoType($type, $data) + { + switch($type){ + case 'boolean': + $data = $data ? true : false; + break; + case 'int32': + $data = intval($data); + break; + case 'int64': + $data = new \MongoInt64($data); + break; + case 'time': + $data = strtotime($data); + break; + case 'date': + $data = new \MongoDate($data); + break; + default: + $data = strval($data); + } + + return $data; + } + } \ No newline at end of file diff --git a/Tiny/Mongo.php b/Tiny/Mongo.php new file mode 100644 index 0000000..d452212 --- /dev/null +++ b/Tiny/Mongo.php @@ -0,0 +1,164 @@ +_setTableName(); + // 连接数据库 + $this->_loadDatabase($name); + } + + public function __set($key, $value) + { + $this->_data[$key] = $value; + } + + private function _loadDatabase($name = 'mongodb') + { + $this->name = $name; + + if (!isset(self::$db[$this->name])) { + $config = Config::config()->{$this->name}; + if(!is_array($config)) + throw new \Exception ($config . ' not a valid db config'); + // Load database + $config['option'] = isset($config['option']) ? $config['option'] : array(); + try{ + $db = new \MongoClient('mongodb://' . $config['host'] . ':' . $config['port'], $config['option']); + }catch (\Exception $e){ + throw new \Exception ('connection mongodb failed'); + } + if(!isset($config['db'])){ + throw new \Exception ('empty mongodb db set'); + } + $db = $db->$config['db']; + + $this->collection = $db->{$this->table}; + self::$db[$this->name] = $db; + } + + $this->collection = self::$db[$this->name]->{$this->table}; + + return $this->getDb(); + } + + public function getDb() + { + return self::$db[$this->name]; + } + + private function _setTableName() + { + if (empty($this->table)) { + $name = get_class($this); + if ($pos = strrpos($name, '\\')) { //有命名空间 + $this->table = $this->_parseName(substr($name, $pos + 1)); + } else { + $this->table = $this->_parseName($name); + } + } + return $this->table; + } + + public function getTableName() + { + return $this->table; + } + + private function _parseName($name, $type = 0) + { + if ($type) { + return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) { + return strtoupper($match[1]); + }, $name)); + } else { + return strtolower(trim(preg_replace('/[A-Z]/', '_\\0', $name), '_')); + } + } + + // 获取主键 + public function getKey() + { + return $this->key; + } + + public function find(array $condition = array(), array $field = array()) + { + $cursor = $this->collection->find($condition, $field); + $rows = array(); + while($cursor->hasNext()){ + $rows[] = $cursor->getNext(); + } + + return $rows; + } + + public function findOne($condition = array(), array $field = array()) + { + if(is_string($condition)){ + return $this->collection->findOne(array($this->key => new \MongoId($condition)), $field); + }elseif(is_array($condition)){ + return $this->collection->findOne($condition, $field); + }else{ + throw new \Exception ('condition must be string or array'); + } + } + + public function delete($criteria, array $option = array()) + { + if(is_array($criteria)){ + return $this->collection->remove($criteria, $option); + }elseif(is_string($criteria)){ + return $this->collection->remove(array($this->key => new \MongoId($criteria)), $option); + }else{ + throw new \Exception ('delete criteria type error'); + } + } + + public function save($data = array(), array $option = array()) + { + if($data){ + return $this->collection->save($data, $option); + }elseif($this->_data){ + return $this->collection->save($this->_data, $option); + }else{ + throw new \Exception ('save data not be empty'); + } + } + + public function update(array $criteria = array(), array $new = array(), array $option = array()) + { + if($criteria && $new){ + return $this->collection->update($criteria, $new, $option); + }elseif($this->_data && isset($this->_data[$this->key])){ + $data = $this->_data; + unset($data[$this->key]); + if(is_string($this->_data[$this->key])) $this->_data[$this->key] = new \MongoId($this->_data[$this->key]); + return $this->collection->update(array($this->key => $this->_data[$this->key]), array('$set' => $data)); + }else{ + throw new \Exception ('update data not be empty'); + } + } + + public static function attributes(){ + return array(); + } +} \ No newline at end of file diff --git a/Tiny/ORM.php b/Tiny/ORM.php index 01e91f2..b5059c3 100644 --- a/Tiny/ORM.php +++ b/Tiny/ORM.php @@ -53,6 +53,7 @@ class ORM { + public $type = 'mysql'; public static $db; // db对象 public static $prefix; // 表前缀 diff --git a/Tiny/Theme/DataTables.php b/Tiny/Theme/DataTables.php index cf2d4d1..4d0f84d 100644 --- a/Tiny/Theme/DataTables.php +++ b/Tiny/Theme/DataTables.php @@ -26,6 +26,7 @@ class DataTables implements tiny\ThemeBuilder public $url = ''; public $action; // action名 public $option; // option + public $model; // 模型名称 public function __construct($action, $option) { @@ -118,35 +119,105 @@ private function _renderPost() isset($this->setting['model']) ? ucfirst(\Tiny\Config::$application) . '\\Model\\' . ucfirst($this->setting['model']) : str_replace('\\Controller\\', '\\Model\\', \Tiny\Request::$controller); - $helper = str_replace('\\Controller\\', '\\Helper\\', \Tiny\Request::$controller); + $this->helper = str_replace('\\Controller\\', '\\Helper\\', \Tiny\Request::$controller); if(!class_exists($model)) \Tiny\Error::echoJson(0, '模型不存在: ' . $model); - if(!class_exists($helper)) - \Tiny\Error::echoJson(0, '辅助类不存在: ' . $helper); + if(!class_exists($this->helper)) + \Tiny\Error::echoJson(0, '辅助类不存在: ' . $this->helper); // 2. 执行helper前置函数 $method = $this->action . 'DataTablesPostBefore'; - if(method_exists($helper, $method)) + if(method_exists($this->helper, $method)) $helper::$method($this->post); - $model = new $model; + $this->model = new $model; // 3. 整理join参数 + $call = '_renderJoin' . ucfirst($this->model->type); + $this->$call(); + + // 4. 整理field, where, order参数 + $msg['js'] = isset($this->setting['js']) ? $this->setting['js'] : ''; + $call = '_renderNormal' . ucfirst($this->model->type); + $this->$call($msg); + if($msg['total'] == 0) + \Tiny\Error::echoJson(2, '好像木有数据...'); + + // 10。处理结果集 + if($msg['rows']){ + $data = array(); + foreach($msg['rows'] as $row){ + $tmp = array(); + foreach($this->setting['column'] as $column){ + if(!$this->_displayColumn($column)) continue; + if(isset($column['name'])){ + // 真实字段名 + $name = isset($column['alias']) ? $column['alias'] : $column['name']; + if(isset($column['call'])){ + switch($column['call']){ + case 'date': + if($row->{$name} && $this->model->type == 'mongodb'){ + $row->{$name} = $row->{$name}->sec; + } + $tmp[] = $row->{$name} ? date('Y-m-d H:i:s', $row->{$name}) : '-'; + break; + case 'date_short': + $tmp[] = $row->{$name} ? date('Y-m-d', $row->{$name}) : '-'; + break; + case 'enum': + $tmp[] = isset($column['enum'][$row->{$name}]) ? $column['enum'][$row->{$name}] : '?(' . $row->{$name}. ')'; + break; + case 'string': + $tmp[] = strval($row->{$name}); + break; + default: + $tmp[] = $this->_callShowRender($column, $this->helper, $row); + } + }else + $tmp[] = !property_exists($row, $name) ? '-' : $row->{$name}; + }else + $tmp[] = $this->_callShowRender($column, $this->helper, $row); + } + $data[] = $tmp; + } + $msg['rows'] = $data; + } + + + // 11. 执行helper后置函数 + $method = $this->action . 'DataTablesPostAfter'; + $helper = $this->helper; + if(method_exists($this->helper, $method)) + $helper::$method($msg); + + // 12. 是否是导出 + if(isset($this->post['_export']) && $this->post['_export']) + tiny\Func::any2excel(array_merge(array($msg['export_title']), $data)); + // 13. 输出结果 + tiny\Error::echoJson(1, $msg); + } + + private function _renderJoinMysql() + { if(isset($this->setting['join'])){ - $model->alias($this->setting['join']['main']); + $this->model->alias($this->setting['join']['main']); foreach($this->setting['join']['on'] as $v){ - $model->join($v['join'], $v['type']); + $this->model->join($v['join'], $v['type']); } } + } - // 4. 整理field, where, order参数 + private function _renderJoinMongodb(){} + + private function _renderNormalMysql(&$msg) + { $field = ''; $whereStr = isset($this->setting['default']['filter']) ? $this->setting['default']['filter'] : '1=1'; $whereBind = array(); foreach($this->setting['column'] as $column){ // export if(isset($this->post['_export']) && $this->post['_export'] && $this->_displayColumn($column)) - $exportTitle[] = $column['title']; + $msg['export_title'][] = $column['title']; if(isset($column['name'])){ // order,需要放前面,不然后面会continue if(isset($this->post['_sort'][$column['name']])) @@ -161,8 +232,9 @@ private function _renderPost() // 执行自定义过滤函数 if(isset($column['filter']['call'])){ $call = $this->action . 'DataTablesFilter' . ucfirst($column['filter']['call']); - if(!method_exists($helper, $call)) + if(!method_exists($this->helper, $call)) \Tiny\Error::echoJson(0, '辅助类中的过滤函数不存在: ' . $call); + $helper = $this->helper; $helper::$call($this->post, $callStr, $callBind); if($callStr && $callBind){ $whereStr .= ' and ' . $callStr; @@ -213,36 +285,36 @@ private function _renderPost() } } } - if($field) $model->field(rtrim($field, ',')); - $model->where($whereStr, $whereBind); + if($field) $this->model->field(rtrim($field, ',')); + $this->model->where($whereStr, $whereBind); - $options = $model->getOptions(); // count后会清楚options,这里需要先获取,后面重新赋值 + $options = $this->model->getOptions(); // count后会清楚options,这里需要先获取,后面重新赋值 // 5. 其他默认配置参数(group,having) if(isset($this->setting['default']['group']) && $this->setting['default']['group']) - $model->group($this->setting['default']['group']); + $this->model->group($this->setting['default']['group']); if(isset($this->setting['default']['having']) && $this->setting['default']['having']) - $model->having($this->setting['default']['having']); - $msg['js'] = isset($this->setting['js']) ? $this->setting['js'] : ''; + $this->model->having($this->setting['default']['having']); + // 6. 统计总记录数 - $msg['total'] = $model->count(); -// echo $model->getLastSql(); - if($msg['total'] == 0) - \Tiny\Error::echoJson(2, '好像木有数据...'); + $msg['total'] = $this->model->count(); +// echo $this->model->getLastSql(); - $model->setOptions($options); + $this->model->setOptions($options); // 7. 整理order if(isset($order)){ if(!in_array($this->post['_sort'][$order], array('asc', 'desc'))) \Tiny\Error::echoJson(0, '排序类型错误: ' . $this->post['_sort'][$order]); - $model->order($order . ' ' . $this->post['_sort'][$order]); + $this->model->order($order . ' ' . $this->post['_sort'][$order]); + }elseif(isset($this->setting['default']['sort'])){ + $this->model->order($this->setting['default']['sort']); }else{ if(isset($this->setting['join'])){ - $model->order($this->setting['join']['main'] . '.' . $model->getKey() . ' desc'); + $this->model->order($this->setting['join']['main'] . '.' . $this->model->getKey() . ' desc'); }else - $model->order($model->getKey() . ' desc'); + $this->model->order($this->model->getKey() . ' desc'); } // 8. 整理limit @@ -261,58 +333,130 @@ private function _renderPost() $msg['current'] = $msg['page']; if($msg['per'] < 10) $msg['per'] = 10; - $model->limit($msg['current'] * $msg['per'] - $msg['per'], $msg['per']); + $this->model->limit($msg['current'] * $msg['per'] - $msg['per'], $msg['per']); } // 9. find结果集 - $msg['rows'] = $model->find(); -// echo $model->getLastSql(); + $msg['rows'] = $this->model->find(); + return $msg; + } - // 10。处理结果集 - if($msg['rows']){ - $data = array(); - foreach($msg['rows'] as $row){ - $tmp = array(); - foreach($this->setting['column'] as $column){ - if(!$this->_displayColumn($column)) continue; - if(isset($column['name'])){ - // 真实字段名 - $name = isset($column['alias']) ? $column['alias'] : $column['name']; - if(isset($column['call'])){ - switch($column['call']){ - case 'date': - $tmp[] = $row->{$name} ? date('Y-m-d H:i:s', $row->{$name}) : '-'; - break; - case 'date_short': - $tmp[] = $row->{$name} ? date('Y-m-d', $row->{$name}) : '-'; - break; - case 'enum': - $tmp[] = isset($column['enum'][$row->{$name}]) ? $column['enum'][$row->{$name}] : '?(' . $row->{$name}. ')'; - break; - default: - $tmp[] = $this->_callShowRender($column, $helper, $row); - } - }else - $tmp[] = is_null($row->{$name}) ? '' : $row->{$name}; - }else - $tmp[] = $this->_callShowRender($column, $helper, $row); + private function _renderNormalMongodb(&$msg) + { + $field = array(); + $where = isset($this->setting['default']['filter']) ? $this->setting['default']['filter'] : array(); + foreach($this->setting['column'] as $column){ + // export + if(isset($this->post['_export']) && $this->post['_export'] && $this->_displayColumn($column)) + $msg['export_title'][] = $column['title']; + if(isset($column['name'])){ + // order,需要放前面,不然后面会continue + if(isset($this->post['_sort'][$column['name']])) + $order = $column['name']; + // field + $field[] = $column['name']; + // where + if(isset($column['filter'])){ + // 执行自定义过滤函数 + if(isset($column['filter']['call'])){ + $call = $this->action . 'DataTablesFilter' . ucfirst($column['filter']['call']); + if(!method_exists($this->helper, $call)) + \Tiny\Error::echoJson(0, '辅助类中的过滤函数不存在: ' . $call); + $helper = $this->helper; + $helper::$call($this->post, $where); // mongodb 的辅助过滤函数只有&$where + }else{ // 内置过滤 + if(!isset($this->post['_filter'][$column['name']]) || $this->post['_filter'][$column['name']] === '') + continue; + switch ($column['filter']['type']) { + case 'date': // 默认的date为int类型 + $where[$column['name']] = strtotime($this->post['_filter'][$column['name']]); + $where[$column['name']] = $this->_renderTypeMongodb($column, $where[$column['name']]); + break; + case 'date_range': + $dateRange = explode('~', $this->post['_filter'][$column['name']]); + $where[$column['name']] = array( + '$gte' => $this->_renderTypeMongodb($column, strtotime($dateRange['0'])), + '$lte' => $this->_renderTypeMongodb($column, strtotime($dateRange['1'])) + ); + break; + case 'range': + if($this->post['_filter'][$column['name']]['0'] !== '' && $this->post['_filter'][$column['name']]['1'] !== ''){ + $where[$column['name']] = array( + '$gte' => $this->_renderTypeMongodb($column, intval($this->post['_filter'][$column['name']]['0'])), + '$lte' => $this->_renderTypeMongodb($column, intval($this->post['_filter'][$column['name']]['1'])) + ); + } + break; + case 'input': // 只有input可进行like处理 + if(isset($this->post['_like'][$column['name']])){ + $where[$column['name']] = new \MongoRegex("/{$this->post['_filter'][$column['name']]}/"); + }else{ + $where[$column['name']] = $this->_renderTypeMongodb($column, $this->post['_filter'][$column['name']]); + } + break; + default: + $where[$column['name']] = $this->_renderTypeMongodb($column, $this->post['_filter'][$column['name']]); + } + } } - $data[] = $tmp; } - $msg['rows'] = $data; } +// var_dump($where); + $mongo = $this->model->collection->find($where); + // 6. 统计总记录数 + $msg['total'] = $this->model->collection->find($where)->count(); + // 7. 整理order + if(isset($order)){ + if(!in_array($this->post['_sort'][$order], array('asc', 'desc'))) + \Tiny\Error::echoJson(0, '排序类型错误: ' . $this->post['_sort'][$order]); + if($this->post['_sort'][$order] == 'asc'){ + $this->post['_sort'][$order] = 1; + }else{ + $this->post['_sort'][$order] = -1; + } + $mongo->sort($this->post['_sort']); + }elseif(isset($this->setting['default']['sort'])){ + $mongo->sort($this->setting['default']['sort']); + } - // 11. 执行helper后置函数 - $method = $this->action . 'DataTablesPostAfter'; - if(method_exists($helper, $method)) - $helper::$method($msg); + // 8. 整理limit + if(!isset($this->setting['page']) || $this->setting['page'] === false){ // 不分页 + $msg['current'] = isset($this->post['_page']['current']) ? $this->post['_page']['current'] : 1; + $msg['per'] = + isset($this->post['_page']['per']) ? + $this->post['_page']['per'] : + (isset($this->setting['page']) ? $this->setting['page'] : 10); + $msg['page'] = ceil($msg['total'] / $msg['per']); + !$msg['page'] && $msg['page'] = 1; + if($msg['current'] < 0) + \Tiny\Error::echoJson(0, '分页参数错误: 当前页需大于0'); + if($msg['current'] > $msg['page']) + $msg['current'] = $msg['page']; + if($msg['per'] < 10) + $msg['per'] = 10; + $mongo->skip($msg['current'] * $msg['per'] - $msg['per'])->limit($msg['per']); + } - // 12. 是否是导出 - if(isset($this->post['_export']) && $this->post['_export']) - tiny\Func::any2excel(array_merge(array($exportTitle), $data)); - // 13. 输出结果 - tiny\Error::echoJson(1, $msg); + // 9. find结果集 + $msg['rows'] = array(); + while($mongo->hasNext()){ + $row = $mongo->getNext(); + $object = new \stdClass(); + foreach($row as $k => $v){ + $object->$k = $v; + }; + $msg['rows'][] = $object; + } + return $msg; + } + + private function _renderTypeMongodb($column, $data) + { + if(isset($column['field_type']) && !is_null($data)){ + $data = tiny\Helper::mongoType($column['field_type'], $data); + } + return $data; } private function _callShowRender($column, $helper, $row) @@ -364,7 +508,7 @@ private function _filter() $html .= ''; if($column['filter']['option']): foreach ($column['filter']['option'] as $k => $v) { - if($value == $k) + if($value === $k) $selected = 'selected'; else $selected = ''; diff --git a/Tiny/Theme/Mod.php b/Tiny/Theme/Mod.php index 60b39ab..8f4383e 100644 --- a/Tiny/Theme/Mod.php +++ b/Tiny/Theme/Mod.php @@ -16,7 +16,9 @@ class Mod implements tiny\ThemeBuilder public $html = ''; // html内容 private $js = ''; private $pkId = null; // model pk id + private $helper = false; //helper private $model = false; // model + private $post = array(); private $data = array(); // model data private $defaultSingleSelect = array( // 默认的single select配置 'enableFiltering' => false, @@ -50,32 +52,55 @@ public function __construct($action, $option) public function build() { if($this->setting && isset($this->setting['mod'])){ - // 组装html - $this->_renderHtml(); - // 输出html - $this->_show(); + if(isset($this->setting['js']) && $this->setting['js']){ + $this->js = $this->setting['js']; + } + foreach($this->setting['mod'] as $k => $v){ + $this->setting['mod'][$v['name']] = $v; + unset($this->setting['mod'][$k]); + } + $this->_renderModel(); + if(tiny\Request::isPost()){ + $this->post = tiny\Request::post(); + $this->_renderPost(); + }else{ + // 组装html + $this->_renderHtml(); + // 输出html + $this->_show(); + } }else echo 'mod setting error'; } - private function _renderHtml() + private function _renderModel() { // model相关 - $this->pkId = tiny\Request::get('id'); - if($this->pkId) { - $this->model = - isset($this->setting['model']) ? - ucfirst(\Tiny\Config::$application) . '\\Model\\' . ucfirst($this->setting['model']) : - str_replace('\\Controller\\', '\\Model\\', \Tiny\Request::$controller); - if(!class_exists($this->model)) - exit('mod model not exists'); - $this->model = new $this->model; - $this->data = $this->model->findOne($this->pkId); + $model = + isset($this->setting['model']) ? + ucfirst(\Tiny\Config::$application) . '\\Model\\' . ucfirst($this->setting['model']) : + str_replace('\\Controller\\', '\\Model\\', \Tiny\Request::$controller); + if(class_exists($model)) { + $this->model = new $model; + } + $this->helper = str_replace('\\Controller\\', '\\Helper\\', \Tiny\Request::$controller); + } - $helper = str_replace('\\Controller\\', '\\Helper\\', \Tiny\Request::$controller); + private function _renderHtml() + { + + if($this->model){ + $pk = $this->model->key; + }else + $pk = 'id'; + + $this->pkId = tiny\Request::get($pk); + if($this->pkId) { + $this->data = (object)$this->model->findOne($this->pkId); + $helper = $this->helper; // 是否有前置处理函数 - $call = lcfirst($this->action) . 'ModBefore'; - if(method_exists($helper, $call)){ + $call = lcfirst($this->action) . 'ModDisplayBefore'; + if(method_exists($this->helper, $call)){ $helper::$call($this->data); } } @@ -127,7 +152,7 @@ private function _renderHtml() 'method' => 'post', 'action' => tiny\Url::get($this->option['action']), 'id' => $this->id, - 'onsubmit' => 'return modCheck();' + 'onsubmit' => isset($this->setting['onsubmit']) ? $this->setting['onsubmit'] : 'return modCheck();' ) ); } @@ -280,6 +305,42 @@ private function _form() return $html; } + private function _renderPost() + { + // save前置函数,用来改变post值 + $before = lcfirst($this->action) . 'ModPostBefore'; + $helper = $this->helper; + if(method_exists($this->helper, $before)){ + $helper::$before($this->post); + } + $model = $this->model; + $attribute = array_keys($model::attributes()); + foreach($this->post as $k => $v){ + if(in_array($k, $attribute)){ + if(is_array($v)) $v = json_encode($v); + if($this->model->type == 'mongodb'){ + if(isset($this->setting['mod'][$k]['field_type'])){ + $v = tiny\Helper::mongoType($this->setting['mod'][$k]['field_type'], $v); + } + } + $this->model->$k = $v; + } + } + + if(isset($this->model->_data[$this->model->key]) && $this->model->_data[$this->model->key]){ + $result = $this->model->update(); + }else{ + if(isset($this->model->_data[$this->model->key])){ + unset($this->model->_data[$this->model->key]); + } + $result = $this->model->save(); + } + if($result) + tiny\Error::echoJson('1', 'success'); + else + tiny\Error::echoJson('1', 'save error'); + } + /** * 获取默认值 * value的优先级最高,其次是id的model值,最后是default