// +---------------------------------------------------------------------- namespace traits\think\model; trait View { protected $viewFields = []; /** * 自动检测数据表信息 * @access protected * @return void */ protected function _checkTableInfo() {} /** * 得到完整的数据表名 * @access public * @return string */ public function getTableName() { if(empty($this->trueTableName)) { $tableName = ''; foreach ($this->viewFields as $key=>$view){ // 获取数据表名称 if(isset($view['_table'])) { // 2011/10/17 添加实际表名定义支持 可以实现同一个表的视图 $tableName .= $view['_table']; }else{ $class = $key.'Model'; $model = class_exists($class)? new $class() : M($key); $tableName .= $model->getTableName(); } // 表别名定义 $tableName .= !empty($view['_as'])? ' '.$view['_as'] :' '.$key; // 支持ON 条件定义 $tableName .= !empty($view['_on'])? ' ON '.$view['_on'] : ''; // 指定JOIN类型 例如 RIGHT INNER LEFT 下一个表有效 $type = !empty($view['_type'])?$view['_type']:''; $tableName .= ' '.strtoupper($type).' JOIN '; $len = strlen($type.'_JOIN '); } $tableName = substr($tableName,0,-$len); $this->trueTableName = $tableName; } return $this->trueTableName; } /** * 表达式过滤方法 * @access protected * @param string $options 表达式 * @return void */ protected function _options_filter(&$options) { if(isset($options['field'])){ $options['field'] = $this->checkFields($options['field']); }else{ $options['field'] = $this->checkFields(); } if(isset($options['group'])){ $options['group'] = $this->checkGroup($options['group']); } if(isset($options['where'])){ $options['where'] = $this->checkCondition($options['where']); } if(isset($options['order'])){ $options['order'] = $this->checkOrder($options['order']); } } /** * 检查是否定义了所有字段 * @access protected * @param string $name 模型名称 * @param array $fields 字段数组 * @return array */ private function _checkFields($name,$fields) { if(false !== $pos = array_search('*',$fields)) {// 定义所有字段 $fields = array_merge($fields,M($name)->getDbFields()); unset($fields[$pos]); } return $fields; } /** * 检查条件中的视图字段 * @access protected * @param mixed $data 条件表达式 * @return array */ protected function checkCondition($where) { if(is_array($where)) { $view = []; // 检查视图字段 foreach ($this->viewFields as $key=>$val){ $k = isset($val['_as'])?$val['_as']:$key; $val = $this->_checkFields($key,$val); foreach ($where as $name=>$value){ if(false !== $field = array_search($name,$val,true)) { // 存在视图字段 $_key = is_numeric($field)? $k.'.'.$name : $k.'.'.$field; $view[$_key] = $value; unset($where[$name]); } } } $where = array_merge($where,$view); } return $where; } /** * 检查Order表达式中的视图字段 * @access protected * @param string $order 字段 * @return string */ protected function checkOrder($order='') { if(is_string($order) && !empty($order)) { $orders = explode(',',$order); $_order = []; foreach ($orders as $order){ $array = explode(' ',$order); $field = $array[0]; $sort = isset($array[1])? $array[1] : 'ASC'; // 解析成视图字段 foreach ($this->viewFields as $name=>$val){ $k = isset($val['_as']) ? $val['_as'] : $name; $val = $this->_checkFields($name,$val); if(false !== $_field = array_search($field,$val,true)) { // 存在视图字段 $field = is_numeric($_field)? $k.'.'.$field : $k.'.'.$_field; break; } } $_order[] = $field.' '.$sort; } $order = implode(',',$_order); } return $order; } /** * 检查Group表达式中的视图字段 * @access protected * @param string $group 字段 * @return string */ protected function checkGroup($group='') { if(!empty($group)) { $groups = explode(',',$group); $_group = []; foreach ($groups as $field){ // 解析成视图字段 foreach ($this->viewFields as $name=>$val){ $k = isset($val['_as'])? $val['_as'] : $name; $val = $this->_checkFields($name,$val); if(false !== $_field = array_search($field,$val,true)) { // 存在视图字段 $field = is_numeric($_field)? $k.'.'.$field : $k.'.'.$_field; break; } } $_group[] = $field; } $group = implode(',',$_group); } return $group; } /** * 检查fields表达式中的视图字段 * @access protected * @param string $fields 字段 * @return string */ protected function checkFields($fields='') { if(empty($fields) || '*'==$fields ) { // 获取全部视图字段 $fields = []; foreach ($this->viewFields as $name=>$val){ $k = isset($val['_as'])? $val['_as'] : $name; $val = $this->_checkFields($name,$val); foreach ($val as $key=>$field){ if(is_numeric($key)) { $fields[] = $k.'.'.$field.' AS '.$field; }elseif('_' != substr($key,0,1)) { // 以_开头的为特殊定义 if( false !== strpos($key,'*') || false !== strpos($key,'(') || false !== strpos($key,'.')) { //如果包含* 或者 使用了sql方法 则不再添加前面的表名 $fields[] = $key.' AS '.$field; }else{ $fields[] = $k.'.'.$key.' AS '.$field; } } } } $fields = implode(',',$fields); }else{ if(!is_array($fields)){ $fields = explode(',',$fields); } // 解析成视图字段 $array = []; foreach ($fields as $key=>$field){ if(strpos($field,'(') || strpos(strtolower($field),' as ')){ // 使用了函数或者别名 $array[] = $field; unset($fields[$key]); } } foreach ($this->viewFields as $name=>$val){ $k = isset($val['_as'])? $val['_as'] : $name; $val = $this->_checkFields($name,$val); foreach ($fields as $key=>$field){ if(false !== $_field = array_search($field,$val,true)) { // 存在视图字段 if(is_numeric($_field)) { $array[] = $k.'.'.$field.' AS '.$field; }elseif('_' != substr($_field,0,1)){ if( false !== strpos($_field,'*') || false !== strpos($_field,'(') || false !== strpos($_field,'.')){ //如果包含* 或者 使用了sql方法 则不再添加前面的表名 $array[] = $_field.' AS '.$field; }else{ $array[] = $k.'.'.$_field.' AS '.$field; } } } } } $fields = implode(',',$array); } return $fields; } }