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;
- }
- }
|