ViewModel.class.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace Think\Model;
  12. use Think\Model;
  13. /**
  14. * ThinkPHP视图模型扩展
  15. */
  16. class ViewModel extends Model {
  17. protected $viewFields = array();
  18. /**
  19. * 自动检测数据表信息
  20. * @access protected
  21. * @return void
  22. */
  23. protected function _checkTableInfo() {}
  24. /**
  25. * 得到完整的数据表名
  26. * @access public
  27. * @return string
  28. */
  29. public function getTableName() {
  30. if(empty($this->trueTableName)) {
  31. $tableName = '';
  32. foreach ($this->viewFields as $key=>$view){
  33. // 获取数据表名称
  34. if(isset($view['_table'])) { // 2011/10/17 添加实际表名定义支持 可以实现同一个表的视图
  35. $tableName .= $view['_table'];
  36. $prefix = $this->tablePrefix;
  37. $tableName = preg_replace_callback("/__([A-Z_-]+)__/sU", function($match) use($prefix){ return $prefix.strtolower($match[1]);}, $tableName);
  38. }else{
  39. $class = $key.'Model';
  40. $Model = class_exists($class)?new $class():M($key);
  41. $tableName .= $Model->getTableName();
  42. }
  43. // 表别名定义
  44. $tableName .= !empty($view['_as'])?' '.$view['_as']:' '.$key;
  45. // 支持ON 条件定义
  46. $tableName .= !empty($view['_on'])?' ON '.$view['_on']:'';
  47. // 指定JOIN类型 例如 RIGHT INNER LEFT 下一个表有效
  48. $type = !empty($view['_type'])?$view['_type']:'';
  49. $tableName .= ' '.strtoupper($type).' JOIN ';
  50. $len = strlen($type.'_JOIN ');
  51. }
  52. $tableName = substr($tableName,0,-$len);
  53. $this->trueTableName = $tableName;
  54. }
  55. return $this->trueTableName;
  56. }
  57. /**
  58. * 表达式过滤方法
  59. * @access protected
  60. * @param string $options 表达式
  61. * @return void
  62. */
  63. protected function _options_filter(&$options) {
  64. if(isset($options['field']))
  65. $options['field'] = $this->checkFields($options['field']);
  66. else
  67. $options['field'] = $this->checkFields();
  68. if(isset($options['group']))
  69. $options['group'] = $this->checkGroup($options['group']);
  70. if(isset($options['where']))
  71. $options['where'] = $this->checkCondition($options['where']);
  72. if(isset($options['order']))
  73. $options['order'] = $this->checkOrder($options['order']);
  74. }
  75. /**
  76. * 检查是否定义了所有字段
  77. * @access protected
  78. * @param string $name 模型名称
  79. * @param array $fields 字段数组
  80. * @return array
  81. */
  82. private function _checkFields($name,$fields) {
  83. if(false !== $pos = array_search('*',$fields)) {// 定义所有字段
  84. $fields = array_merge($fields,M($name)->getDbFields());
  85. unset($fields[$pos]);
  86. }
  87. return $fields;
  88. }
  89. /**
  90. * 检查条件中的视图字段
  91. * @access protected
  92. * @param mixed $data 条件表达式
  93. * @return array
  94. */
  95. protected function checkCondition($where) {
  96. if(is_array($where)) {
  97. $view = array();
  98. // 检查视图字段
  99. foreach ($this->viewFields as $key=>$val){
  100. $k = isset($val['_as'])?$val['_as']:$key;
  101. $val = $this->_checkFields($key,$val);
  102. foreach ($where as $name=>$value){
  103. if(false !== $field = array_search($name,$val,true)) {
  104. // 存在视图字段
  105. $_key = is_numeric($field)? $k.'.'.$name : $k.'.'.$field;
  106. $view[$_key] = $value;
  107. unset($where[$name]);
  108. }
  109. }
  110. }
  111. $where = array_merge($where,$view);
  112. }
  113. return $where;
  114. }
  115. /**
  116. * 检查Order表达式中的视图字段
  117. * @access protected
  118. * @param string $order 字段
  119. * @return string
  120. */
  121. protected function checkOrder($order='') {
  122. if(is_string($order) && !empty($order)) {
  123. $orders = explode(',',$order);
  124. $_order = array();
  125. foreach ($orders as $order){
  126. $array = explode(' ',trim($order));
  127. $field = $array[0];
  128. $sort = isset($array[1])?$array[1]:'ASC';
  129. // 解析成视图字段
  130. foreach ($this->viewFields as $name=>$val){
  131. $k = isset($val['_as'])?$val['_as']:$name;
  132. $val = $this->_checkFields($name,$val);
  133. if(false !== $_field = array_search($field,$val,true)) {
  134. // 存在视图字段
  135. $field = is_numeric($_field)?$k.'.'.$field:$k.'.'.$_field;
  136. break;
  137. }
  138. }
  139. $_order[] = $field.' '.$sort;
  140. }
  141. $order = implode(',',$_order);
  142. }
  143. return $order;
  144. }
  145. /**
  146. * 检查Group表达式中的视图字段
  147. * @access protected
  148. * @param string $group 字段
  149. * @return string
  150. */
  151. protected function checkGroup($group='') {
  152. if(!empty($group)) {
  153. $groups = explode(',',$group);
  154. $_group = array();
  155. foreach ($groups as $field){
  156. // 解析成视图字段
  157. foreach ($this->viewFields as $name=>$val){
  158. $k = isset($val['_as'])?$val['_as']:$name;
  159. $val = $this->_checkFields($name,$val);
  160. if(false !== $_field = array_search($field,$val,true)) {
  161. // 存在视图字段
  162. $field = is_numeric($_field)?$k.'.'.$field:$k.'.'.$_field;
  163. break;
  164. }
  165. }
  166. $_group[] = $field;
  167. }
  168. $group = implode(',',$_group);
  169. }
  170. return $group;
  171. }
  172. /**
  173. * 检查fields表达式中的视图字段
  174. * @access protected
  175. * @param string $fields 字段
  176. * @return string
  177. */
  178. protected function checkFields($fields='') {
  179. if(empty($fields) || '*'==$fields ) {
  180. // 获取全部视图字段
  181. $fields = array();
  182. foreach ($this->viewFields as $name=>$val){
  183. $k = isset($val['_as'])?$val['_as']:$name;
  184. $val = $this->_checkFields($name,$val);
  185. foreach ($val as $key=>$field){
  186. if(is_numeric($key)) {
  187. $fields[] = $k.'.'.$field.' AS '.$field;
  188. }elseif('_' != substr($key,0,1)) {
  189. // 以_开头的为特殊定义
  190. if( false !== strpos($key,'*') || false !== strpos($key,'(') || false !== strpos($key,'.')) {
  191. //如果包含* 或者 使用了sql方法 则不再添加前面的表名
  192. $fields[] = $key.' AS '.$field;
  193. }else{
  194. $fields[] = $k.'.'.$key.' AS '.$field;
  195. }
  196. }
  197. }
  198. }
  199. $fields = implode(',',$fields);
  200. }else{
  201. if(!is_array($fields))
  202. $fields = explode(',',$fields);
  203. // 解析成视图字段
  204. $array = array();
  205. foreach ($fields as $key=>$field){
  206. if(strpos($field,'(') || strpos(strtolower($field),' as ')){
  207. // 使用了函数或者别名
  208. $array[] = $field;
  209. unset($fields[$key]);
  210. }
  211. }
  212. foreach ($this->viewFields as $name=>$val){
  213. $k = isset($val['_as'])?$val['_as']:$name;
  214. $val = $this->_checkFields($name,$val);
  215. foreach ($fields as $key=>$field){
  216. if(false !== $_field = array_search($field,$val,true)) {
  217. // 存在视图字段
  218. if(is_numeric($_field)) {
  219. $array[] = $k.'.'.$field.' AS '.$field;
  220. }elseif('_' != substr($_field,0,1)){
  221. if( false !== strpos($_field,'*') || false !== strpos($_field,'(') || false !== strpos($_field,'.'))
  222. //如果包含* 或者 使用了sql方法 则不再添加前面的表名
  223. $array[] = $_field.' AS '.$field;
  224. else
  225. $array[] = $k.'.'.$_field.' AS '.$field;
  226. }
  227. }
  228. }
  229. }
  230. $fields = implode(',',$array);
  231. }
  232. return $fields;
  233. }
  234. }