| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 | <?php// +----------------------------------------------------------------------// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]// +----------------------------------------------------------------------// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.// +----------------------------------------------------------------------// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )// +----------------------------------------------------------------------// | Author: liu21st <liu21st@gmail.com>// +----------------------------------------------------------------------namespace Think\Model;use Think\Model;/** * ThinkPHP视图模型扩展  */class ViewModel extends Model {    protected $viewFields = array();    /**     * 自动检测数据表信息     * @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'];                    $prefix     =   $this->tablePrefix;                    $tableName  =   preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $tableName);                }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   =   array();            // 检查视图字段            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 = array();            foreach ($orders as $order){                $array = explode(' ',trim($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 = array();            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 =   array();            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 =  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;    }}
 |